# BakingTray Documentation

Serial-section extension for ScanImage

BakingTray is an open source [ScanImage](https://www.mbfbioscience.com/products/scanimage/) wrapper written at the [Sainsbury Wellcome Centre Microscopy Facility](https://swc-advanced-microscopy.github.io/facility_webpage/) for performing automated serial-section tile scanning within [MATLAB](http://www.mathworks.com/). BakingTray was inspired by the [TeraVoxel](https://github.com/TeravoxelTwoPhotonTomography) ([Economo, et al](https://elifesciences.org/articles/10566)) and [MouseLight](https://github.com/MouseLightPipeline) ([Winnubst, et al](https://www.sciencedirect.com/science/article/pii/S0092867419308426?via%3Dihub)) projects and is made public for research and development purposes.

![](/files/-MAW_FyCC1ofszuTE3nA)

## Who is it for?

BakingTray is *not* scanning software: it is a wrapper around the [ScanImage](https://www.mbfbioscience.com/products/scanimage/) [API](https://github.com/SWC-Advanced-Microscopy/ScanImageAPI_Examples). This software is aimed at technically-minded people who want to experiment with serial-section imaging and have full control over all aspects of the process. Setting up BakingTray from scratch on your rig requires *significant effort*, good MATLAB programming skills, knowledge of ScanImage, and the know-how to set up and run a 2-photon microscope. *This is not a turn-key solution*. BakingTray will run on any microscope hardware supported by ScanImage.

## How does it work?

BakingTray is based upon an [existing tile-scanner extension for ScanImage](https://github.com/SWC-Advanced-Microscopy/ScanImageTileScan), simply adding the ability to slice the sample after each section. Imaging itself is performed via ScanImage, which is freely available MATLAB-based software for running 2-photon microscopes.

## Current features

This software has been thoroughly stress-tested and is capable of generating production-quality data. The current feature set is as follows:

* Easy sample set up: take a fast preview image of the sample then draw a box around the area to be imaged. An Auto-ROI feature is available for adaptively imaging only the tissue.
* Acquisition of up to four channels using resonant or linear scanning.
* A low-resolution preview image of the current section is assembled in real time.
* Graceful acquisition abort (either immediately or at the end of the current section) and pausing.
* Automatically halts if the laser drops out of modelock.
* PMTs and laser automatically switch off at the end of the acquisition.
* Support for multiple lasers via Scanimage.
* Easy control of illumination as a function of depth via ScanImage.
* Integrates with our [StitchIt](https://github.com/SWC-Advanced-Microscopy/StitchIt) software for assembling the stitched images from raw tiles.
* Easily resume a previously halted acquisition.
* Imaging of multiple samples at once.
* Modular API allows developers to easily extend the software or adapt it to different hardware.
* Slack messages on acquisition completion.

## What do the results look like?

See the [Gallery](/developers/gallery).

## How to get it?

Find the project [on GitHub](https://github.com/SWC-Advanced-Microscopy/BakingTray).


# Hardware requirements

This page describes the hardware you ought to have to run BakingTray using ScanImage.

## Acquisition PC

If you're building from scratch, buy the fastest Intel-based computer you can. Prioritise CPU speed over number of cores, since ScanImage runs single threaded. Otherwise, any moderately fast PC should work.

We originally acquired images to a local RAID array: four platter drives in RAID 1+0. The striping is necessary when using a resonant scanner. Unless you anticipate very large datasets, 4 TB drives should be sufficient. For over a year now we been acquiring to a single 8 TB SSD and this has worked well.

Hardware of course goes out of date quickly, but the following is an example of a successful configuration for resonant scanning.

{% hint style="success" %}

* i7-6700K @ 4 GHz, 16 GB DDR4-2133 MHz RAM, H170-Pro motherboard
* Adaptec RAID 6405E, 4x WD Black RAID 1+0.
* NVIDIA GeForce GT 730 to drive a pair of DELL U2715H monitors. Otherwise the on-board graphics are fine.
* Oxford Semiconductor 4 port PCIe serial adaptor for PIFOC and motion control hardware (laser comms via motherboard serial port).
  {% endhint %}

A PCIe serial adapter card will have a lower latency than USB-serial and so is preferable. Install the card in the lowest bus number possible on your motherboard. If you do not do this, Windows will re-assign COM port numbers when you change other hardware (e.g. swap out or move an NI card in the chassis).

The hardware RAID above is necessary as a single platter drive won't provide enough bandwidth for resonant scanning. You don't need RAID for galvo scanning. You can substitute a single SSD for resonant scanning. Samsung currently make [8 TB SSDs](https://www.samsung.com/uk/memory-storage/sata-ssd/ssd-870-qvo-sata-3-2-5-inch-8tb-mz-77q8t0bw/) with a warranted life of 3 years or 2,880 TB.

## Data acquisition devices

BakingTray works with any scanning hardware and acquisition cards [supported by ScanImage](http://scanimage.vidriotechnologies.com/display/SI2019/Supported+Microscope+Hardware), including the vDAQ. For resonant scanning with four channels on NI hardware we use:

{% hint style="success" %}

* Chassis: NI PXIe-1073
* Image acquisition: NI PXIe-7961R FPGA and NI-5734 digitizer
* PIFOC, Pockels, and scan control: 3x PXIe-6341
* Abalog PMT control: older versions of ScanImage required a four channel NI USB-6343 but now you can use 2x NI USB-6009 devices, which is far cheaper.
  {% endhint %}

### Galvo scanning DAQs

We have run galvo/galvo using both [NI PCI-6110](http://www.ni.com/en-gb/shop/select/multifunction-io-device?modelId=122555) and [NI PCI-6115](http://www.ni.com/en-gb/shop/select/multifunction-io-device?modelId=122566) acquisition cards. However, PXIe devices are recommended as they're easier to manage in a chassis. The [PXIe-6124](http://www.ni.com/en-gb/shop/select/pxi-multifunction-io-module?modelId=123694) has also been tested but higher sample speeds don't work on all motherboards.

## Scanning Hardware

* We recommend *resonant scanning* as it is much faster for high resolution images even though there is an increase in shot noise due to the shorter dwell time. Using moderate PMT gains will help with the shot noise and will have no negative consequences. For example, set multialkali PMTs to about 500V rather than the 700 or 800V that are typically used for *in vivo* imaging. This will result in reduced amplification; there will be no decrease in sensitivity. Averaging frames is also possible, but for bright labeling this not needed. Unlike linear scanning at short line periods, the bidirectional "comb" artifact is virtually gone with resonant scanning as it is constant across the scan line.\
  We have tried 12 kHz, 8 kHz, and 4 kHz [resonant scanners](http://www.cambridgetechnology.com/products/components-specialty-products#resonant-scanners) and all work. However, we do not recommend the 12 kHz scanner as lower scan angle produces an excessively small field of view which results in more stage motions. The 8 kHz scanner will image samples faster in practice, since fewer tiles are needed to cover the sample.
* A 400 micron travel range PIFOC (we use a [P-725.4CDA](https://www.physikinstrumente.co.uk/en/products/nanopositioning-piezo-flexure-stages/pifoc-objective-pinano-sample-scanners-for-microscopy/p-725-pifoc-long-travel-objective-scanner-200375/)) is recommended for optical sectioning as it is the most flexible option. However, shorter travel range PIFOCs are faster and are acceptable if you are certain you will never want to image cleared tissue.
* You will need a [Pockels cells](https://www.conoptics.com/modulation-systems) to ramp laser power with depth. Choose one with a low dispersion crystal and the BK option to reduce resonances.

## The microscope

You ideally want a microscope capable of imaging a large FOV (>1 mm) that is flat and undistorted. The FOV affects scanning speed: if you have a small FOV the tile scanning becomes slow. For our purposes a flat field would be one with less than 10 microns of sag in focal plane. If you lack this, everything will still work but it can be trickier to get good overlap of features at tile edges. "Distortion" refers to pincushion and barrel distortion: the less of this the better. Again, you can work with a microscope that exhibits it. We care about distortion because it affects tile overlap areas when stitching images (although some degree of correction is possible).

You can image an EM grid such as the 2145C from [2spi](http://www.2spi.com/category/grids) to assess FOV and distortion. For field flatness tou can take a z-stack through [one of these slides](https://spectraservices.com/product/vs-fluorcal.html), or make your own by cover-slipping a small drop of fluorescein solution.

You will want at least a manual coarse focus stage with 20 mm of travel for the objective. Ideally a motorized coarse z stage: this is easier to use.

For objectives: a Nikon 16x NA 0.8 objective works well and you don't need to spend more to get good results unless you are planning on routinely imaging fine structures (under about one micron).

## Lasers

BakingTray interacts with the laser to turn it off at the end of acquisition and stop acquisition if the laser fails to modelock. The system has been well tested with MaiTai and Chameleon lasers. We've run these rigs with both Spectraphysics and Coherent lasers and don't have a strong preference. You need only worry about a pulse compressor if your pulses are under 100 fs and you have a lot of glass in your system (e.g. optically conjugated scanners).

The system can run with multiple lasers simultaneously, since this is supported by ScanImage. However, BakingTray currently only monitors the modelock state of one laser. There is no facility currently for re-imaging sections at a different wavelength or with a different laser.

## Motion Hardware

The sample sits in a water bath atop an X/Y/Z stage.

We have had good results with PI stages and generally use these, however Zaber stages also work well. Any stage from these manufacturers will likely be [supported out of the box](https://github.com/SainsburyWellcomeCentre/BakingTray/tree/master/code/components/motion) or will require only very minor code changes. However, choosing a stage with good properties is key: see below. BakingTray is modular, so it's easy to [add classes to support stages from other manufacturers](/developers/developers/motion-control-classes).

### The stage

You will need a high quality, heavy-duty, 3-axis stage. This stage will translate the sample in X/Y for tile scanning and also raise it in Z and move in X for slicing. The sample stage will be controlled by BakingTray, not ScanImage. Motions in the X/Y plane need to be as fast and accurate as possible, since the microscope spends much of its time just moving the sample.

{% hint style="success" %}
Known to work well are the [PI V-551](https://www.physikinstrumente.co.uk/en/products/linear-stages-and-actuators/stages-with-linear-motors-friction-free-magnetic-direct-drive/v-551-pimag-precision-linear-stage-1200204/#description) direct-drive stage and C-891 controllers. We use 130 mm of travel for X and 60 mm of travel for Y.
{% endhint %}

Also known to work are PI M-531.DD, and PI M-605.2DD. Tests indicate that Zaber's [X-LDA stages](https://www.zaber.com/products/linear-stages/X-LDA-AE) should work very well, but no microscope is yet built with them. You would need the 150 mm and 75 mm stages. Using cheaper stages is not recommended: the reliability of the stage is critical.

The best option for the vertical stage (Z-jack) right now is the [Prior FB204](https://www.prior.com/product/fb204-z-axis-motorized-focus-mounts). This has 38 mm of travel and a 14 kg load limit. Buy it with a basic controller with no joystick. A hardware-based joystick is not needed and could even cause problems. Zaber's [X-VSR40A](https://www.zaber.com/products/vertical-stages/X-VSR/specs?part=X-VSR40A) 40 mm lift stage looks good and should pair well with their X-LDA stages (above). We have not yet tried this Zaber stage on a rig, however. Avoid Aerotech: they dropped MATLAB support in 2024 when they upgraded their motion control library.

BakingTray is highly modular, and it's fairly easy to modify the software to use stages from other vendors will require a little coding to set them up.

### Constructing the XYZ stage

The X/Y stages can be mounted directly on top of an AeroTech lift stage (you will need to machine a coupler). The AeroTech stage can in turn be mounted on a breadboard with three ThorLabs [BLP01 adjustable height legs](https://www.thorlabs.com/newgrouppage9.cfm?objectgroup_ID=1740\&pn=BLP01) for tilt correction.

## Vibratome

You can use any vibratome. The vibratome can be gated either [via TTL](https://github.com/SainsburyWellcomeCentre/BakingTray/blob/master/code/components/cutting/JaneliaLeicaController.m) or with a [FaulhaberMCDC](https://github.com/SainsburyWellcomeCentre/BakingTray/blob/master/code/components/cutting/FaulhaberMCDC.m) serial-based DC motor controller. A nice option is a Leica VT-1000 vibratome head and blade, which can be purchased as spare parts from the manufacturer. The vibratome does not need a linear motor: it will not translate, the slicing is all done by the XYZ stage. Choose a vibratome based around a DC motor, as these work well and are robust. Avoid voice-coil solutions, which can be temperamental when used in a way the manufacturer did not anticipate. You should mount the vibratome in a way that allows you to control the [roll axis of the blade](/users/troubleshooting/acquisition-problems-and-solutions).

## Microscope motors

### Zaber

Your microscope should be fixed in X and Y. Do not use microscope that can translate in these axes, as this could result in a hardware crash. A coarse Z motor is very useful, however. Zaber are a good source of these. Zaber controllers are adaptable and can be used with motors from other vendors, such as ThorLabs. The Zaber control wheel by default switches between position and velocity mode if you press the wheel button. You should disable this for safety reasons. This can be done in Zaber's software using the trigger feature as follows:

```
/1 trigger 1 when 1 knob.mode == 0
/1 trigger 1 action a 1 knob.mode = 1
/1 trigger 1 enable
```

This assumes your X-MCB1 controller is set to device 1, so if not, just replace the first `1` in each command with the actual device number.


# Known issues

In general BakingTray is very stable and almost all acquisitions complete without errors. The full list of issue can be found on the [BakingTray issue tracker](https://github.com/SWC-Advanced-Microscopy/BakingTray/issues). The more notable issues are as follows:

* During acquisition with linear scanners [Issue #20](https://github.com/SWC-Advanced-Microscopy/BakingTray/issues/20) or a high level of averaging with resonant scanners [Issue #234](https://github.com/SWC-Advanced-Microscopy/BakingTray/issues/234) there are multiple instances of duplicate tiles appearing in the preview window. This does not affect the saved data.
* We use an [NI USB-6343](http://www.ni.com/en-gb/support/model.usb-6343.html) to control the PMT gains. This works but we see the following bug: there is a rare chance that, when BakingTray is open, [switching off the PMTs causes MATLAB to crash](https://github.com/SainsburyWellcomeCentre/BakingTray/issues/13). We work around this by disabling PMT auto-on and having BakingTray issue the PMT off command at the conclusion of acquisition only. We experience no problems or acquisition failures when working like this.

## Hardware-related issues.

* PROBLEM: Coherent lasers rarely switch off or close the shutter during the first section. This has never happened later in the acquisition. SOLUTION: Deleting the files in the acquisition directory and re-starting the acquisition.


# Initial Installation


# Software installation

Setting up the acquisition PC and installing required software and drivers.

Before proceeding, ensure you are familiar with the [hardware requirements](/getting-started/hardware_requirements).

## Windows

BakingTray requires Windows and will not run on Linux or Mac OS. Installs have been known to run on Windows 7, 10, and 11. If possible install [Windows LTSC](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/ltsc-what-is-it-and-when-should-it-be-used/ba-p/293181) as it is less aggressive with updates and has less useless crap installed by default.

### Disabling Random Windows Reboots

{% hint style="warning" %}
You must ensure that Windows will not attempt to install updates or reboot the system without permission.
{% endhint %}

If using Windows 7 ensure you select the update setting that allows the user to choose when to install updates. For Windows 10 and 11 the story [is more complicated](https://www.windowscentral.com/how-stop-updates-installing-automatically-windows-10#disable_automatic_windows_update_regedit). It is still recommended you install updates when the system is idle: BakingTray will not be affected if you do this.

### Ensure Windows Does Not Enter Sleep Mode

Configure the Windows Power settings such that the PC will never go to sleep when unattended.

## Data storage and RAID

You will want at least 4 TB of local storage, on a physical volume separate from the OS drive. If you have a resonant scanner this must be either an SSD or a platter disk striped RAID with at least two drives (2 disk RAID 0 or 4 disk RAID 0+1). A single 8 TB SSD works very well.

### Raid Mode

{% hint style="warning" %}
Consult your motherboard manual and set the on-board SATA ports to RAID mode if necessary *before* installing Windows. Windows is stupid and fails to boot if you switch to RAID mode afterwards.
{% endhint %}

In the event that you do need to switch SATA mode and Windows complains (it will likely BSOD) then you can try the following

1. Just boot it into safe mode and it should automatically install the RAID drivers. After booting into safe mode once it should then be able to boot normally. If this fails, check whether the RAID drivers are installed (look on motherboard manufacturer' website and download the drivers) then try again.
2. <http://www.askvg.com/how-to-change-sata-hard-disk-mode-from-ide-to-ahci-raid-in-bios-after-installing-windows>

## Software versions

BakingTray has not been extensively tested on a range of MATLAB and ScanImage versions. Only general indications are provided here. It is the intention that BakingTray can be run on recent MATLAB and ScanImage versions, so you should feel free to use the latest versions of both and [file an Issue](https://github.com/SWC-Advanced-Microscopy/BakingTray/issues) if something fails. However, it is known that certain combinations do not work. MATLAB R2019b to R2021b are known to work with ScanImage SI Free v5.6-1 up to Basic 2023.0.0. MATLAB versions R2022b and R2023b seem not to be compatible with ScanImage (at least up Basic 2023.0.0).

## Install Software

After installing Windows and any hardware drivers you must install the following software:

* [MATLAB](https://www.mathworks.com/products/matlab.html). You should install the following toolboxes: Curve Fitting, Data Acquisition, Image Acquisition, Image Processing, Parallel Computing, Signal Processing, Statistics & Machine Learning. Some of those are not currently used by BakingTray but they may be in the future so it's easier to install them if possible. If you lack some of those toolboxes, just install as many as possible and [file an Issue](https://github.com/SWC-Advanced-Microscopy/BakingTray/issues) if you run into problems.
* [NI DAQmx v 19.0](https://www.ni.com/getting-started/install-software/data-acquisition) or newer if you do not have a vDAQ.
* PI software that came with your hardware: PI GCS, PI MATLAB GCS2, Stage database, USB driver, PIMikroMove, PITerminal, PIUpdateFinder

The following software is useful but not critical

* [Putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)
* [7-Zip](https://www.7-zip.org/)
* [Faulhaber motion manager](https://www.faulhaber.com/en/support/faulhaber-motion-manager/)
* [WinSCP](https://winscp.net/eng/download.php)
* TeamViewer (or similar)
* [Git for Windows](https://gitforwindows.org/). This is used in the absence of a MATLAB package manager.

{% hint style="warning" %}
We have noticed rare random hard-crashes of MATLAB in later releases (for sure in R2019a and R2019b). These were traced to 3D acceleration and occurred on both Win 7 and Win 10. Updating Nvidia drivers did not help but starting MATLAB in software OpenGL mode did get rid of the problem.
{% endhint %}

If using PI stages, install the PI drivers for the stages and follow the instructions for setting up the MATLAB PI interface. If you need to install the SDK in order to compile the PI drivers, [you may find this link useful](http://ch.mathworks.com/matlabcentral/answers/101105-how-do-i-install-microsoft-windows-sdk-7-1). The PI MATLAB code will need to be in your path. It should be located at `C:\Users\Public\PI\PI_MATLAB_Driver_GCS2` once installed.

### Installation and configuration of ScanImage

* Install [ScanImage](http://scanimage.vidriotechnologies.com/). The old version (5.6.x) will probably work but BakingTray is compatible with SI Basic, which is much nicer and buying it gets you tech support from Vidrio.
* Follow the steps in [Setting Up ScanImage](/getting-started/initial-installation/setting-up-scanimage)
* Now is a good time to [check the noise on your amplifiers](/getting-started/finishing-the-install/exploring-amplifier-noise-and-bias-in-scanimage).

### Installation of BakingTray

Clone the `master` branch of [BakingTray](https://github.com/SainsburyWellcomeCentre/BakingTray) and add to your path:

* `code`
* `code/resources`
* `code/components` and its sub-directories

You can use the function at `BakingTray/addBTtopath.m` to do this or, better yet, do it with a `setup.m` file containing the line of this sort:

```
addpath(genpath('C:\MATLAB\BakingTray\code'))
```

This way you are robust to possible future changes in the directory structure. The `pathtool` GUI will also work if you prefer, but do not add the base BakingTray directory and all its sub-directories: this may have unintended consequences.


# Setting up ScanImage

Basic set up of ScanImage for use with BakingTray

## Setting Up ScanImage

### USR and CFG files

ScanImage settings can be stored for recall later. Two sets of files are used: "user settings" files and "configuration files". These are outlined [here](http://scanimage.vidriotechnologies.com/display/SI2019/CFG+and+USR+Files).

Briefly, there will probably be one user settings file that you'll use to start ScanImage each time. It stores things like the window positions and which channels are active. So set up this sort of thing and save it as a user settings file which you call "BakingTray.usr" or similar.

Then set up some configuration files for different scan settings. These ".cfg" files will save stuff like the image size, if the pixels are square, the bidirectional scan phase correction, the PMT gains, etc.

At this point you should [calibrate the number of microns per pixel](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/initial_installation/calibration/Calibrating-the-number-of-microns-per-pixel-with-ScanImage.md).

### Scan amplitude

Adjust the scanner settings until the mirrors are moving at their maximum amplitudes at a zoom setting of 1. You might find (either now or in the future) that pressing Grab or Loop generates an error like this:

```
Error using scanimage.components.scan2d.resscan.Control/start (line 153)
NI DAQmx error (-200462) in call to API function 'DAQmxStartTask':
 Generation cannot be started because the output buffer is empty.

Write data before starting a buffered generation. The following actions can empty the buffer: changing the size of the buffer, unreserving a task, setting the Regeneration Mode property, changing the Sample Mode, or configuring
retriggering.
```

One way this can happen is if the waveform of the galvo is too large. Check this as follows:

```
>> max(hSI.hWaveformManager.scannerAO.ao_volts_raw.G)

ans =

         0   10.0527

>> min(hSI.hWaveformManager.scannerAO.ao_volts_raw.G)

ans =

         0  -10.0527
```

The DAQ is capable of producing values between +/- 10 V, so this is the problem.

### Z scan settings

The PIFOC will be controlled by ScanImage and now is a good time to get to know it and ensure it's behaving well. Mount the objective you will be using into the PIFOC. Run the [actuator tuning](http://scanimage.vidriotechnologies.com/display/SI2019/Using+the+Actuator+Tuning+Window) and set up reasonable parameters for, say, 5 depths spaced 10 μm apart. Use the step mode. Make sure you set reasonable default values for the [Fast Z](http://scanimage.vidriotechnologies.com/display/SI2016/Fast+Z+Controls) controls. We find that a flyback time of about 35 ms and a lag of about 5 ms is suitable for most scenarios. You [should test this](http://scanimage.vidriotechnologies.com/display/SI2019/FastZ+Tuning+Window) for your hardware and save these values in the configuration file. BakingTray will automatically enable Fast Z when it starts scanning and will use whatever flyback and lag settings are already there.

#### Channel names

In the PMT set up dialog in ScanImage you should name the channels appropriately. This matters because the autoROI algorithm that finds the samples works best using the Red PMT. The far-red PMT tends to have too little autofluoresence and in the blue the agar has a lot of autofluorescence at longer excitation wavelengths. You should name your PMTs "Red", "Green", and "Blue". If you have "Far Red" also, that is fine: the system will ignore it when choosing the channels. The names are case-insensitive. Just don't name the PMTs anything else, like "Low", "Med", "Short" or "<490 nm", etc. If you do not name the PMTs the autoROI algorithm will choose the brightest channel upon which to work.

On ScanImage Basic the PMTs should be set up in the same order as the channels so that the first PMT is associated with channel 1, etc. If channel 1 is unused, make a dummy PMT. Suggested PMT names for Basic: "Chan 1: RED", "Chan 2: GREEN", etc Make sure you add the colon.

#### vDAQ wiring

BakingTray uses line `D0.0` for the external trigger. **NOTHING MUST BE CONNECTED TO THIS LINE** e.g. set up the resonant sync signal on a different line. If you connect the resonant sync signal to `D0.0` then tile scanning will behave strangely and fail.

#### Other settings

* ScanImage has the ability to blank the laser turn-arounds. This is mainly used to avoid photo-damage *in vivo* when using resonant scanners (and to a lesser extent linear scanners). We don't care much about bleaching and photo-damage, since our tissue is dead and we image each frame only once. On the other hand, the blanking can lead to ringing in the amplifier for samples with high autofluoresence or where this bright signal near the tile edges. The ringing is systematic and will be removed when the average tile is divided out. Disable flyback blanking in ScanImage with caution, therefore.
* In SI Basic the PMT GUI has a number of annoyances, one of which is that it is not very salient when the PMTs turn on (this has been fixed from Basic 2022 onwards). You can change the colour of the PMTs icon in the ON state to make it more obvious. To do this you will need to edit the file `+dabs\+resources\+widget\+widgets\PMTWidget.m` Around line 62 you will see the definition for the PMT on state image. The color is defined by a constant that comes from dictionary. The default is `most.constants.Colors.darkGrey`. You can change this. e.g. you might choose `darkGreen` for the ON state.

### Displaying power in mW in ScanImage

It is very helpful to be able to display to the user power in mW rather than percent power. However, since laser power and offset varies with wavelength, BakingTray needs to update ScanImage as the user changes wavelength. To set this up you will need to ensure that ScanImage able to run the power calibration using a photodiode. See the instructions in ScanImage docs for this. If you do not have a photodiode in your path then you can use a power meter with an analog output at the objective, so long as the sensor is fast enough. You can also reflect the laser light off a piece of white paper after the objective and place a photodiode next to that temporarily. Before starting, make sure the Pockels offset has been set. You can only do this at one wavelength. e.g. choose a wavelength and always use the same one (such as 920 nm) or choose a wavelength in the middle of your range (such as 850 nm). A perfect offset is not very important due to the higher laser powers we are using.

The process for calibrating ScanImage with BakingTray is:

1. Open the Laser GUI in BakingTray.
2. Turn on the laser and open the shutter.
3. Set desired wavelength in the laser GUI.
4. In ScanImage run the beam calibration function from the beams widget. You should get a nice smooth curve with the calibration tool.
5. Measure min and max power and set these manually in the MDF GUI under the laser. You can access this from the gear icon on the beams widget.
6. Confirm with power meter that the curve makes sense by looking at a few different values. It is normal to be off by about 10% and for low values (e.g. 10 mW) to be off by 50%. For the values typically used for imaging, however, it should be accurate enough.
7. Run BakingTray.utils.addLaserCalib. This will store the information in a .MAT file and over-write any existing calibration at the same wavelengths, should this exist.
8. Run this for your commonly used wavelengths. e.g. 920 nm, 800 nm, 780 nm. When you change wavelength, BakingTray will look for the closest calibration file. e.g. if you go to did the above three calibrations and you go to 930 nm, it will load the 920 nm calibration. If the laser wavelength is more than 20 nm from any existing calibration file, then it will not report laser power at all.

You may list existing calibrations with `BakingTray.utils.listLaserCalib`

{% hint style="info" %}
You can automate the setting of the min and max values using `mpqc.record.power` from <https://github.com/SWC-Advanced-Microscopy/multiphoton-qc>. This requires a ThorLabs power meter to be connected via USB. Install drivers before first connecting. We have found it's much easier to accurately set the power this way, as the intercept term is hard to obtain manually.
{% endhint %}

If the calibrations fail, check you have a clean signal coming into the DAQ by temporarily looking at the analog input signal in NI MAX. e.g. check your breakout box is set to SE and if necessary you have a terminator in place on the BNC terminal below the on you are recording from.

The above has been tested with ScanImage Basic 2022.3.0 and should work in some earlier versions also. The upcoming release after 2022.3.0 will show power in mW in the BEAMS window. Currently power is only shown in the Beam widget and without a vDAQ only in point mode. This is remedied by the upcoming release.

{% hint style="warning" %}
Newer versions of BakingTray accommodate multiple laser lines. If you perform the calibration and save to disk then change the beam name component, BakingTray will NOT apply the calibration. It will FAIL SILENTLY!
{% endhint %}

## Upgrading ScanImage

At least for more recent releases of SI Basic, the procedure for manually updating ScanImage is very straightforward:

* Download the manual installer and unpack to a location of your choice.
* Copy the known working MDF (and user config files if appropriate) into the directory.
* Change the path and start ScanImage.
* When requested, point ScanImage to the location of the copied MDF file.
* Instruct ScanImage to load your user settings on startup by supplying its location in the startup window.
* Verify that laser power calibrations are still correct and redo if necessary.

That should be it. Perhaps the automatic installer is more straightforward but we have not tested this. Across some earlier releases of ScanImage there were large changes in settings files, which made the above a bit more awkward.

### Choosing scan settings for linear scanners

This setting is for user who have galvos only (no resonant scanner). A resonant scanner is recommended if at all possible. The purpose of this section is to describe how to get a feeling for how long it will take to acquire data with linear scanners and what the images will look like. Before proceeding with this step you should [calibrate the number of microns per pixel](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/initial_installation/calibration/Calibrating-the-number-of-microns-per-pixel-with-ScanImage.md). Linear scanners are slow and driving them too hard has trade-offs with image quality. Here is how to determining scan settings and approximate imaging times:

Set up ScanImage as follows (PMTs and laser can be off):

1. Channels dialog: display chan 1, check save boxes for largest number of channels you anticipate using.
2. Set up saving into a junk directory.
3. Set up the fast z controls (if you use this): step, check enable, set up your typical number of optical sections and distance between sections.
4. In MAIN CONTROLS: set "acqs" to acquire 10 to acquisitions
5. In User functions add `BT_timer` (which will need to be in you path) to 'acqModeStart', 'frameAcquired', and 'acqDone', 'acqMode'
6. The pixels/line affects microns per pixel. Set zoom to 1 and makes sure Pix=Lin is checked in CONFIGURATION. Suggested pixels per line: between 500 and 1024. At larger numbers (will depend on your PC), you will get faster performance if you also disable viewing of chan1
7. Set the pixel bin factor and sampling rate to get a line period of around 750 to 900 microseconds. You can go as low as 650 with some scanners, but that's not recommended. The image quality will get better above 800 microseconds, since the bidi scan artefacts are largely gone here.
8. Now hit loop.

It then reports reasonable acquisition times: e.g. For 11x15 tiles of 5x10 microns in 220 physical sections

Our setup yields the following times:

* 41 hours - 892 microsecond scan lines, 0.98 mics/pix, 2.0 MHz
* 33 hours - 716 microsecond scan lines, 0.98 mics/pix, 2.5 MHz
* 33 hours - 716 microsecond scan lines, 0.98 mics/pix, 2.5 MHz (NO CHAN 1 DISPLAY)
* 49 hours - 856 microsecond scan lines, 0.77 mics/pix, 4.0 MHz
* 106 hours - 834 microsecond scan lines, 0.52 mics/pix, 2.0 MHz (with chan1 display)
* 77 hours - 834 microsecond scan lines, 0.52 mics/pix, 2.0 MHz (WITHOUT chan1 display)

Now repeat but with 3x10 microns and 370 physical sections

* 35 hours - 716 microsecond scan lines, 0.98 mics/pix, 2.5 MHz

The above numbers will of course be faster for resonant scanning, which uses an FPGA.


# Hardware setup


# Motor Setup


# PI stage setup

If you are using PI stages, you should ideally optimize their motions using PI MikroMove. The following is a list of things to do, but without detailed instructions.

* First of all take a record of the factory settings of your stages. Right-click on each axis, select "Show Exapanded Single-Axis Window"
* Load the stage with the water bath and fire up the data recorder for each axis: click the axis name in the menu and select "Show data recorder". Make steps of the sizes you typically use during tile scanning. Look at the curves. They should settle in under about 150 ms with a target velocity of 25 mm/s. A V-551-2B stage can settle in under 100 ms. A faster velocity does not help because the stages will not achieve it over such a short distance. You will need to adjust the number of recorded data points or sampling rate (bottom left) to see the whole curve. If the stage position poorly follows the command position then you can try tuning the PID loops (see below). If the command position is changing too quickly, try increasing the speed and acceleration.
* Ensure that the stages are also able to perform large motions (20 or 30 mm).
* You can confirm all is good by imaging pollen grains and moving the stages.
* Note that with larger step sizes and faster speeds the water in the bath can cause image to oscilate for a short while. If this is problematic: decelerate more gradually, use slower speeds, reduce the water bath volume.
* Once all steps are complete and the microscope is assembled, you can set the soft limits (min and max positions) for the X and Y axes so that even at the firmware level, stages can't accept out of bounds motion commands that would cause hardware damage. BakingTray has its own soft-limits, though, so this step is optional.

## Tuning the PID loops

* The direct-drive stages have separate loops for position and velocity.
* Other stages have multiple loops for other purposes. If your tuning changes do nothing, try a different loop.
* Enable the display of the startup parameters. This will make going back to the original values easier.
* Set the I and D terms to zero. Set P to a low number (e.g. 10). Perform a step of the size and speed typical of tile scanning.
* Keep doubling P until you see oscillations, then halve it.
* Set I to a small number (e.g. 5) and keep doubling it as long as the curve improves. Look for where it settles to a steady state and has reached the target position. Keep going until it oscillates then halve it. If the curve looks good earlier then you don't need to push that far.
* Tweak D if needed, but otherwise leave at zero.
* [More info here](https://www.crossco.com/blog/basics-tuning-pid-loops).

Once well tuned a V-551 stage can make a 1.25 mm stage in about 100 ms whilst loaded with a water bath:

![](/files/nNv8ltBFYkhRZsVJLmTO)

## Hints and tips

* Ensure that the stage really is settling as expected. e.g. If you are are planning on moving in 1 mm steps and settling well within, say, 200 ms then make sure that you can successfully issue 1 mm motion steps every 200 ms. Ensure that every so often the stages aren't taking much longer to settle. This can happen and it will really slow down your acquisitions. Tweak PID parameters until this no longer a problem.


# Calibrating a linear actuator

Calibrating a linear actuator

These instructions apply if you need to calibrate an uncalibrated linear actuator to receive motion commands in mm.

## Connecting to the device

Before proceeding with this step ensure the area surrounding the stage is clear of obstructions. Remove the objective, the water bath, and the blade holder. The [motion control classes page](/developers/developers/motion-control-classes) describes how BakingTray handles motion control hardware. Briefly, each physical motion axis consists of a linear stage and a controller for that stage. BakingTray represents these as separate software entities: a class that inherits `linearstage` represents the stage and a class that inherits `linearcontroller` represents the stage controller. To connect to the TC1000 Z-jack from the command line we first need to build the stage class then attach it to the controller:

```
% Make an instance of the Haydon 43k4U linear stage class
>> tStage=haydon43K4U
tStage = 
  haydon43K4U with properties:

          positionUnits: 'mm'
                 axisID: ''
         invertDistance: 1
         positionOffset: 0
    controllerUnitsInMM: 1
               axisName: []
                 minPos: []
                 maxPos: []
% That creates an instance of the class. This instance needs to be 
% populated with reasonable settings:
>> tStage.minPos=0;
>> tStage.maxPos=40;
>> tStage.axisName='zAxis';
>> tStage.controllerUnitsInMM=1.5305E-4; % We'll show how to derive this later
```

Now it's time to make an instance of the controller.

```
% The controller class for this Z-jack is an AMS_SIN11. Let's make an instance of 
% that and attach it to the stage we just made:
>> A = AMS_SIN11(tStage);

% The following command will connect to the device and then immediately start 
% a downward reference motion until it reaches the lower limit switch. This will
% be considered the zero position. Locations upward from this are positive. 
% YOUR SYSTEM MUST HAVE FUNCTIONAL LIMIT SWITCHES FOR THE REFERENCING MOVE TO WORK
>> A.connect('COM8');
Device returned:
 K= 5/ 3,I= 2001/ 1,V= 10014/ 1,E= 100,,1/10thn=A
Homing axis on AMS_SIN11..

% Indeed it considers itself to be at 0 mm
>> A.axisPosition
ans =
     0

>> A.absoluteMove(10); %move up 10 mm
>> A.axisPosition
ans =
   10.0000

% Do not disconnect yet from the device.
```

## Calibrating

The stepper motor controller instructs the motor how many steps to take, it doesn't know anything about the number of mm the actuator has traveled. The conversion factor of mm to steps was defined above as:

```
tStage.controllerUnitsInMM=1.5305E-4;
```

This value is correct for our hardware but you should derive it again here. For this you will need a [Mitoyo measuring gauge sold by ThorLabs](https://www.thorlabs.de/thorproduct.cfm?partnumber=DGM05) and an [arm of some sort](https://fisso.com/en/fisso-products/fisso-produkte/) to clamp it to. You can clamp to the thicker portion with a 9.5 mm diameter right below the main body (see the ThorLabs CAD PDF from the link above). The arm holding the gauge can be strong, so take care not to damage the gauge by driving the stage into it.

![](/files/wJKJTcIiR59qfuibdKPo)

```
>> A.absoluteMove(15);
>> A.absoluteMove(10); % We will move down next. This gets rid of backlash
>> A.attachedStage.controllerUnitsInMM=1; % scaling factor is now one to one
>> A.attachedStage.maxPos=1E6; % Or the controller refuses to move the axis
```

Now set to the measuring gauge and make a note of the reading. Move the stage down by 10,000 steps:

```
A.relativeMove(-10000);
```

Take a note of the reading again. The calibration value is the difference between those readings divided by 10,000. In our case:

```
>> (3.218-1.687)/10000
ans =
   1.5310e-04
```

That's very close to the value of 1.5305E-4 which we had measured previously. Enter your value as shown below and return the max pos to a safe value

```
>> A.attachedStage.controllerUnitsInMM=1.310E-4; %Your value here
>> A.attachedStage.maxPos=40;
>> A.absoluteMove(10); % Get everything back as before
```

Your Z-jack should now be calibrated.

## Ensure repeatability is good

Confirm that the stage moves as expected by taking a few 1 mm steps and reading the value of the gauge:

```
>> A.relativeMove(-1);
>> A.relativeMove(-1);
>> A.relativeMove(-1);
>> A.relativeMove(-1);
>> A.relativeMove(-1);
```

Ignore a value obtained right after a change of direction. To confirm that the referencing is repeatable you should move to an absolute position (10 mm in the following example), place the gauge at that point and take a reading, then reference the stage and move back there.

```
>> A.absoluteMove(10); % Note reading on gauge
>> A.referenceStage;
Homing axis on AMS_SIN11.................
>> A.absoluteMove(10); % Note the reading again
```

Repeat the above two or three times. The readings at the start and end should match pretty closely. If the readings are about 100 microns out, that is likely OK.


# Verifying stage motions


# Setting up a VT1000 vibratome

## Setting up a Faulhaber motor controller with a Leica VT1000

The Leica VT1000 vibratome head works well and requires just a DC motor controller. The motor and encoder in a VT1000 is made by Faulhaber so if you buy a Faulhaber motor controller it is easy to run the unit at a defined RPM. The motor is a Faulhaber 3540K012C ([datasheet](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/hardware_setup/Faulhaber/Motor_specs_EN_3540_C_DFF.pdf)) connected to a HEDS-5500 encoder ([datasheet](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/hardware_setup/Faulhaber/Encoder_specs__EN_HEDS-5500_DFF.pdf)). The following instructions are written assuming you are using a Faulhaber MCDC 3006 S RS controller. These are no longer made (but are available on Ebay) and the new model (MC5005 S RS) is NOT a drop-in replacement because it does not have a reasonable serial interface any more. We are looking for a suitable replacement device.

It is a good idea to connect the encoder, since you have it and you will get better control of motor speed this way.

{% hint style="info" %}
There are instructions further down below for what to do if you did not (or can not) hook up the encoder.
{% endhint %}

### Connecting the controller

Hook up the motor to a 12V DC 1 A supply.

![Faulhaber\_establish\_connection](/files/hVQftGa3dDUZFg3dvuWC)

Snip off the green connector coming off the motor on the vibratome, strip the leads, and tin the bare wires.

![snip\_strip\_tim](/files/WCww7ARcOvM4rWdaRYaK)

Hook up to the controller as shown below. Note the far right motor +/- leads power the motor; here these wires looker thicker for those cables as the originals were extended. The thinner black and red wires are power for the encoder. The encoder sensor wires are the remaining two: white and brown.

![Faulhaber\_Motor\_connections](/files/VWK7UamyRlkGmfOfcHsc)

Finish off the install by hooking up the serial cable to the PC (with the MC5005 S RS you can use a USB cable). Power on the device!

### Connect to the controller

The following instructions are for [Faulhaber Motion Manager 6](https://www.faulhaber.com/en/support/faulhaber-motion-manager/), which you should install now. Note it is possible your version of Motion Manager 6 won't look exactly like what is shown below, but it should be close enough.

Click "Establish Connection" in the top left. Select the COM port of your device then "Next". The select the first entry in the drop-down ("Motion Control V2.x") and select "Next", then "Next" through the next window.

![Faulhaber\_establish\_connection](/files/o9RW95eh8UBzWaWypGjF)

You will then see a window that lists your controller:

![Faulhaber\_Connection\_to\_device](/files/0ius7hQ8m6jcMbNJJ8in)

Click "Finished" and the main window will now look like this:

![Faulhaber\_Connected\_full\_window](/files/3Paf3F4JkKyuN5lzBEGm)

### Set the drive parameters

Press "Select motor" under the "Establish connection" button. You will need to make a motor with the right properties. Press "Create" in the following window:

![Faulhaber\_motor\_selection](/files/uTlgNXXMKsDqYFeM9Exo)

Now fill in the next window as follows:

![Faulhaber\_motor\_selection\_\_edit\_motor](/files/LxDZTIz6M6ivEoj9cSM9)

Press "Next" and in the next window you will enter the properties of the motor. You might find that your window looks different to the following. In which case use the [3540K012C datasheet](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/hardware_setup/Faulhaber/Motor_specs_EN_3540_C_DFF.pdf) to find the correct values. Remember that in this datasheet `1,7` means `1.7`.

![Faulhaber\_Motor\_selection\_properties](/files/fVYpGdOEPw9G1oScUnQX)

Now "Save". Confirm the settings on the original page look as follows. The encoder is a HEDS-5500-A which has a spec sheet that says it has 500 lines/rev. So set the pulses per rev to 500 pulses/rev. Correct that if needed and hit "Next"

![Faulhaber\_motor\_selection](/files/uTlgNXXMKsDqYFeM9Exo)

Skip the next window describing the gear train ("Load transmission"). Just "Next" through it.

In the following window ("Factor of inertia"), J\_Load should be "20".

![Faulhaber\_Motor\_Selection\_Factor\_of\_inertia](/files/mtXQLI2Emok01ppkKdcV)

In the next window, just press 'Next' to select the default "quiet running".

"Finished" on the summary page. This sends the parameters to the motor and you should say "Yes" when offered to store these to the device.

You can test the device by going to the "Operate motor" section and running the motor at 3200 RPM, which is the default speed in BakingTray.

The motor should run almost silently with the blade holder and blade attached, assuming everything is bolted down tightly. Quit the software.

### Confirming the vibratome can communicate with BakingTray

You should have already added BakingTray to your path. The following sample session shows how to start up the class for controlling the vibratome and sending commands to it.

```
>> f=FaulhaberMCDC('COM2'); % connect to the vibratome on COM port 2
```

If you have run through all of the steps, ensure that the controller is in the correct mode for running with the encoder:

```
>> f.set2CONTMOD;
```

You do not need to run that again: the mode of the encoder has been stored to its non-volatile memory.

You can now control the motor in RPM:

```
>> f.startVibrate(1000);  % 1000 RPM
>> f.startVibrate(2000);  % 2000 RPM
>> f.stopVibrate; % Stops the motor
>> delete(f) % disconnects from the controller
```

## Running without the encoder

If you could not set the motor up with the encoder using the above steps then follow this section. Perform the following steps with the vibratome securely mounted, blade in blade holder, and blade holder mounted. Nothing should be loose. Do not excessively tighten things, though, this is not needed.

{% hint style="warning" %}
Without the encoder it is easy to run the vibratome motor far harder than the manufacturer intended. Start at slow speeds and be sure you know how to cut power to the device if you need to.
{% endhint %}

The following sample session shows how to start up the class for controlling the vibratome and sending commands to it.

```
>> f=FaulhaberMCDC('COM2'); % connect to the vibratome on COM port 2
Setting up Faulhaber MCDC3006 DC motor controller.
Motor max speed: 60 revs per second.
```

You now need to tell the controller to run without the encoder:

```
>> f.set2IXRMOD;
```

You do not need to run that again: the mode of the encoder has been stored to its non-volatile memory.

```

%Let's start a gentle vibration
>> f.startVibrate(5); % You should now see a modest vibration of the blade
>> f.stopVibrate;  % And we stop it
```

You should consider the sample speed setting, which is the input argument to `startVibrate`, to be in arbitrary units. The goal now is to identify a reasonable speed setting for slicing the sample.

```
% Try a range of speeds and stop once it becomes more noisy
>> f.startVibrate(10); % quiet
>> f.startVibrate(11); % quiet
>> f.startVibrate(12); % still quiet
>> f.startVibrate(13); % Getting loud: vibrations are clearly audible
>> f.startVibrate(10); % <--- Back off a few steps. Make a note of this setting.
>> f.stopVibrate;

% Terminate the session
>> delete(f)
Closing connection to Faulhaber MCDC motor controller
```

If you run the vibratome too fast you will wear our the axle or the bearings and may need to replace the whole unit after a year or two. Make a note of the vibrate speed chosen above. You will later use this when making the BakingTray settings file and only modify if it if you notice cutting problems.

Note that BakingTray can also run devices such as the Leica VT1200 (the unit used by [Economo et al](https://elifesciences.org/articles/10566)) by gating its operation with a TTL pulse via the [JaneliaLeicaContoller](https://github.com/SWC-Advanced-Microscopy/BakingTray/blob/master/code/components/cutting/JaneliaLeicaController.m) class.


# Setting up the laser

Multi-photon microscopy relies on the laser emitting light in short pulses rather than continuously. This pulsing, also known as "modelocking", it critical for fluorescence emission.\
BakingTray communicates with the laser in order to stop acquisition should it drop out of modelock. BakingTray also turns off the laser when acquisition completes. Available laser control classes are in the [components/laser](https://github.com/SWC-Advanced-Microscopy/BakingTray/tree/master/code/components/laser) directory.

Let us say you have a Chameleon laser and it is connected to your motherboard serial port, COM1. The following sample session confirms we can connect to the laser and demonstrates some features of the laser control class. Substituting `chameleon` for `maitai` will allow communication with a Spectraphysics Mai Tai.

```
>> c=chameleon('COM1');

Setting up Chameleon laser communication on serial port COM1
Connected to Chameleon laser on serial port COM1

>> [~,status]=c.isReady
status =
    'Laser not powered on'
% So let's turn on the laser with the key switch...

% Test if laser shutter is open (0 means it's closed, 1 means it's open)
>> c.isShutterOpen
ans =
     0
>> c.openShutter; % Let's open the shutter
>> c.isShutterOpen
ans =
     1
% Yep, shutter is now open

% Let's read and then change the wavelength
>> c.readWavelength
ans =
   920

>> c.setWavelength(940);
>> c.readWavelength
Failed to read wavelength from Chameleon. Likely laser is tuning.
ans =
   NaN

% Wait 5 seconds...
>> c.readWavelength
ans =
   940
% Nice

% Close communications with the laser
>> delete(c)
Disconnecting from Chameleon laser
Closing serial communications with Chameleon laser
```

With BakingTray in your path confirm you can communicate with the laser as above. Make a note of the COM port you are using, you will need this later for completing the settings file.

## GDD compensation

The laser GUI in BakingTray does not control any GDD compensation you may have available. If your laser has a pre-chirper, ensure that it is set up correctly across wavelength. If you have dielectric mirrors in the path, confirm that required GDD compensation values do not change drastically over small (e.g. 5 or 10 nm) changes in wavelength. If this does occur, you will need to track down the mirror or mirrors which are causing the effect and swap them out (ideally with metal-coated mirrors).

## Notes on power modulation

If you are modulating power using an external EOM, such as a Conoptics Pockels cell, you should consider making it possible to automatically switch this device on and off with the laser. The laser will be turned off automatically when acquisitions complete. EOMs have limited lifetime and you will save many hours if the unit is switched off with the laser. To achieve this you will need to build or buy a mains extension lead which has a TTL-switchable relay. BakingTray can interface with such a relay. Instructions for setting this up are detailed in the instructions for filling in the settings files.

## Dealing with poor modelocking behavior at specific wavelengths

Lasers will sometimes pulse poorly at a narrow range of wavelengths. The resulting images will show high-frequency stripes and tend to look dimmer than normal. Fixing this requires a service visit of some sort. Whilst waiting for the visit, you can block users from using problem wavelengths. For instance, to block users from the 770 -- 790 nm range and also the 920 -- 925 nm range you can do:

```
hBT.laser.bannedWavelengths = {[770,790],[920,925]};
```

To avoid having to type this in every time you start BakingTray, you can add this line to the `startup_bt.m` file in your BakingTray SETTINGS folder.

## Banned wavelengths

Tunable lasers sometimes fail to modelock in particular wavelength ranges and need servicing. You can block users from accessing those ranges temporarily. To do this, create a `startup_bt.m` file in your BakingTray SETTINGS folder. To block 910 to 920 nm you would add to this file:

```matlab
hBT.laser.bannedWavelengths={[910,920]};
```

If you wanted to also block 810 to 850 nm you would do:

```matlab
hBT.laser.bannedWavelengths={[810,850; 910,920]};
```

The contents of `startup_bt` are run when BakingTray starts. You can also run the above lines in the terminal to confirm the blocking is working.


# Finishing the install


# Check the noise on your amplifiers

You may want to adjust the bias setting on your amplifiers (e.g. if you are using [Femto amplifiers](https://www.femto.de/en/products/current-amplifiers/variable-gain-up-to-200-mhz-dhpca.html)) and maybe de-noise. This is easy to do from within ScanImage. Turn off the PMT power supply, bring up all the channels windows and press "Focus". Then right-click on each channel window and show the histogram. It should look something like this (click for larger version):

![](/files/UBlH0Q2HocYxFeGiNwfg)

Ensure that the offset subtraction for each channel is switched off by unchecking the checkboxes. The roughly Gaussian distribution which you see arises from various forms of electrical noise In this case you can also see a ripple pattern that comes from the amplifier. The offset on Channel 1 is slightly negative. The digitizer we are using is 16 bit so the scale goes up to +/- 2^15 (32768).

In this case our goals are to reduce the noise and also to adjust the offsets to make them 0V, if desired. (If you wish, you could set set the offset to negative extreme of your digitization range, which would double the available dynamic range. StitchIt can [calculate the actual zero offset](https://github.com/SainsburyWellcomeCentre/StitchIt/commit/c553da5209a3b6c770af25353dcfd804f009c42c) to handle a biased amplifier.)

## Tweaking the bias.

Simply turn the offset set-screw on your amp whilst imaging until the peak of the curve is at zero. On the Femto you want the offset screw not the bias screw. You may offset to a negative number to increase dynamic range.

## Denoising

At least on the Femtos it's possible to get rid of the annoying ripple noise but you will need to spend a little time messing around. Things that you can try including grounding the chassis of all the amplifiers or resting them on foil which you ground. After a little messing around, we now have this (click for larger version showing all four channels):

![](/files/bfcADtDKmEZz23I4pm4D)

Channel 1 is a little noisier than the others and there are some funny streaks in Channel 2, but overall things are much better. Remember: here we're looking at signals right at the low end of the digitizer's input range.


# Starting BakingTray

Starting BakingTray for the first time

You should by now have run through the detailed hardware checks before proceeding with the instructions on this page.

### Making default settings files

At the command line run `BakingTray`. You will see something like this at the command prompt:

```
Starting construction of BT object
Can not find system settings file: making default file at C:\MATLAB\BakingTray\SETTINGS\systemSettings.yml
BT is reading default component settings

 **** Can not find a component settings file in C:\MATLAB\BakingTray\SETTINGS\
 **** Copying an empty file to this location but you will need to edit it ****

** Laser not defined in component settings file
** Cutter not defined in component settings file
** Scanner not defined in component settings file
** No motion axes defined


 BakingTray starting...
 Connecting to hardware components:

** Laser not defined in component settings file
** Cutter not defined in component settings file
** Scanner not defined in component settings file
** No motion axes defined
BT.attachMotionAxes failed to build one or more axes. Not starting BT.
Cleaning up BT object
BakingTray failed to create an instance of BT. Quitting.
```

BakingTray failed to start but created default settings in a `SETTINGS` sub-directory within the BakingTray directory. You will now edit these settings files for you hardware. Before proceeding, familiarise yourself with the information on the [settings files](/getting-started/finishing-the-install/the-settings-files).

### Editing the settings file

* The component settings file describes the hardware BakingTray will use.
* Navigate to the `SETTINGS` sub-directory and open the `componentSettings.m` file in an editor. For now set the maximum and minimum stage positions to reasonably large values: we'll deal with them in detail later.
* Edit the file and re-run `BakingTray`. There are instructions in the file describing how it should be edited based on the information you gathered when [verifying the hardware](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/finishing_the_installation/Verifying-hardware-operation.md).

### Editing the system settings file

* The system settings file describes the system as a whole.
* As before, information on editing the file is [described here](/getting-started/finishing-the-install/the-settings-files).

### The default recipe

* Also in the settings directory is a file called `default_recipe.yml`. The recipe files define the properties of an acquisition. When you start BakingTray, `default_recipe.yml` is read. You may edit this file so BakingTray starts with different defaults. You may create multiple such files and manually load one after BakingTray starts. e.g. different recipes for different organ types.

## Finalising hardware settings

At this point you should be able to start BakingTray without errors and, if necessary, have at least roughly tweaked the X/Y stage [PID loops](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/finishing_the_installation/PI-Stage-Setup.md). The most important task right now is to ensure that the stages can not produce an motion that would cause a hardware crash:

{% hint style="danger" %}
Be careful with the following steps. Go slowly so as not to damage your hardware.
{% endhint %}

* Place the vibratome and blade holder with blade in the correct position with respect to the objective. e.g. So the blade centered on the objective and the blade tip is about 30 mm from the axis of the objective.
* Assemble the stages and place an empty water bath on top.
* You can leave the objetive off for now in order to avoid damageing it.
* Set the X/Y stages to 0 (their mid-points) and move the XYZ stage so that the middle of the sample is under where the objective would be.
* Bolt the stage into place.
* Raise the water bath until the waterbath lip is level with the widest part of the blade holder. Move the Y stage and determine the maximum and minimum positions you can go without the blade holder hitting the lip of the water bath.
* Perform the same check for the X stage. Motions of the X stage could cause the bath to hit the vibratome or the objective. You may, therefore, want the objective in place when making this measurement.
* Carefully raise the Z stage and determine the point at which the blade comes within about 0.5 mm of the sample platform. This is is the maximum Z position.
* Edit the config file. Restart BakingTray. Ensure the positions are honoured. You might need to restart MATLAB for the new values to be honoured.

{% hint style="info" %}
With PI stages it's possible to define soft limits for the motions in PI Mikromove. For extra safety, set the limits in MikroMove then also set the limits in the BakingTray settings file. It's best to set slightly narrower limits in the BakingTray settings file so you will not get an out of bounds error from the stages.
{% endhint %}

{% hint style="danger" %}
Altering blade tile (pitch) will require updating the max Z axis position.
{% endhint %}

### Calibrations

* The three-axis stage should be [aligned with the imaging plane](/getting-started/finishing-the-install/calibration/basic-calibrating-procedures).
* It is important that you [accurately calibrate](/getting-started/finishing-the-install/calibration/calibrating-the-number-of-microns-per-pixel-with-scanimage) the number of microns per pixel in ScanImage. BakingTray uses this number to figure out where to move the stages. Also note the optional [fine-tuning](/getting-started/finishing-the-install/calibration/fine-tuning-positioning-accuracy) procedure.


# Settings Files

BakingTray uses configuration files located in the `SETTINGS` directory. The configuration files are:

1. `systemSettings.yml` -- defines properties of the rig as a whole
2. `componentSettings.m` -- describes how BakingTray should connect to each piece of hardware/
3. `frameSizes.yml` -- defines image sizes and stitching parameters.
4. `SIBT_settings.yml` -- defines a small number of settings associated with the BakingTray/ScanImage bridge.
5. `startup_bt.m` -- this optional MATLAB script runs each time BakingTray starts

It will require multiple passes through all the files to get everything dialed in correctly. The following description is broken down by settings file.

## System Settings

The so-called "system settings" are those that describe parameters of the rig that are unlikely to change between sessions. This includes things like how fast the stages are supposed to move, and general features of the cutting cycle. `BakingTray.settings.readSystemSettings` parses `systemSettings.yml` and creates it if does not already exist. Here is what each parameter means:

### Main system settings

* `SYSTEM.ID` - A string defining the unique name of your microscope. This will allow you to distinguish between different microscopes should you have multiple systems. You can set this right now, but it's a good idea not to change the name once the system becomes productive.
* `SYSTEM.xySpeed` - The target maximum speed of your X/Y stage in mm/s. You can leave this alone.
* `SYSTEM.cutterSide` - set to `1` if the vibrotome is on the right as you look at the system. Set to `-1` if the vibrotome is on the left.
* `SYSTEM.homeZjackOnZeroMove` - If 1 the Z stage is zeroed each time the user asks for it to go to the lowest position (0 mm). 0 otherwise. Do this if your Z-jack has no encoder, otherwise it is not needed.
* `SYSTEM.dominantTilingDirection` - The stage axis which will conduct the bulk of the motions in the S-shaped tile scan. It makes sense to set this as being the top stage in your stack, as this will be carrying the smallest load. However you should watch a sample translate in X and Y at your highest desired resolution and check if one axis induces oscillations over long periods. We have seen cases when, for examples, there is wobble in the image induced by the top stage that lasts for a second or so but this is not induced by the lower stage. If this happens and you can not fix the wobble, just set the dominant tiling direction to the better stage. The default value, which you may well not have to change, is `y`.
* `SYSTEM.defaultSavePath` - The default path to bring up for saving data. If missing or not valid we use the current directory instead. Likely you are saving data to a separate RAID array or SSD. In this case set it to the drive letter: `D:\` or whatever. Doing this reduces user errors and questions regarding to where data should be saved.
* `SYSTEM.autoROIchannelOrder` - By default this is the list `{'red','green','blue'}`. It is suggested to leave like this. The red channel is best for the auto-ROI algorithm, as the agar fluoresces least in this channel. You can leave this setting as it is.
* `SYSTEM.bladeXposAtSlideEnd` - Scalar corresponding to the the X stage position associated with when the blade just reaches the edge of the slide.
* `SYSTEM.slideFrontLeft` - A vector of length 2 defining the X/Y position at which the objective is directly over the front/left corner of the slide.
* `SYSTEM.raisedZposition` - The position the Z stage should go to when the "Raise sample" button is pressed. If not supplied, the button will do nothing.
* `SYSTEM.raisedXposition` - The position the X stage should go to when the "Raise sample" button is pressed. If not supplied, the button will do nothing.

### How to set the blade and stage position values

Filling in these settings will require an operational system, with all stages functional. Place a blade in the blade holder and mount on the vibratome.

#### SYSTEM.bladeXposAtSlideEnd

You will need a water bath in the system. Raise the the water bath until the blade is within about 5 mm of the platform. Translate the water bath along the X axis until the tip of the blade is level with the end of the platform. Read off the X stage value and enter this in the `SYSTEM.bladeXposAtSlideEnd` section of the YML file in mm.

#### SYSTEM.slideFrontLeft

You will need a water bath with an empty slide clamped onto the platform. The bath should be half-filled with water.\
Turn on the laser, tune it to 750 nm, "POINT" the beam and set power to about 10 mW. Translate the X and Y stages such that the white frosted part of the slide under the objective and raise the bath until the beam is near focus: about 1 mm in diameter. Translate the water bath until the focused spot is at the front/left corner of the slide. Enter the X and Y stage values in mm in the `SYSTEM.slideFrontLeft` section of the YML file in the format \[X\_mm, Y\_mm]

#### SYSTEM.raisedXposition and SYSTEM.raisedZposition

Before the system can slice a sample the user must defining a cutting start point by translating the sample in Z and X. To simplify this process there is a "Raise Sample" button, which the user can press after the water bath has been loaded. This button raises the sample to a safe position at which the sample is near the blade but definitely will not hit it. You must define this position using the `SYSTEM.raisedZposition` and `SYSTEM.raisedXposition`. If undefined, the "Raise Sample" button will simply do nothing. Glue to a slide one or more agar blocks representing the largest possible sample that might be loaded into the system. For example, you might glue into place two rat brains spaced quite far apart. Move the sample such that it is near the sample, as [shown in the usage instructions](/users/user_guide/step_03_preparing-the-sample), however leave a very comfortable gap between the blade and the agar. Note down the positions of the X and Z stages and enter these into the settings file at `SYSTEM.raisedXposition` and `SYSTEM.raisedZposition`.

### Settings related to cutting

* `SLICER.approachSpeed` - The speed in mm/s with which the sample is brought to the cutting start point. You can leave this at around 25 mm/s. It's not critical.
* `SLICER.vibrateRate` - Vibration frequency of the blade. This will be in RPM, assuming you have [set up the motor controller to use the encoder](/getting-started/hardware-setup/setting_up_vt1000). It is recommended you go through those steps.
* `SLICER.postCutDelay` - Number of seconds to wait for the cut slice to settle to the bottom of the bath. About 5 seconds is reasonable.
* `SLICER.postCutVibrate` - The vibrate rate to use during the post-cut delay period. We find that hugely reducing the blade speed (e.g. to 3 Hz) allows the slice to slide off the blade. See also `SLICER.vibrateRate` , above.
* SLICER.defaultYcutPos - Scalar defining the Y position at which we cut. This depends on the water bath and vibratome position and is not sample-dependent. Find the Y stage value at which the blade midpoint is centered on the slide. Enter this value here in mm.

### Slack message settings

The `SLACK` settings in the `systemSettings.yml` file are there to provide a Slack hook which is used by BakingTray to send progress messages to a Slack channel. This section is optional and is filled out as follows:

```
SLACK:
  user: '@MicroscopeName'
  hook: 'https://hooks.slack.com/services/T7S8UFJKL/CVG8T59LP/lKW6o9bw88jrEnJ87T27Ie2m1'
```

The `user` setting is simply the microscope name and is appended to the message. The `hook` is a string the corresponds to a [web hook you create for a Slack channel](https://api.slack.com/messaging/webhooks). Once you have completed the above, restart BakingTray and test your Slack integration:

```
>> hBT.slack('This is a test message')
```

There is no feedback to the command line but you should see the Slack message appear on the target channel.

## Component Settings

The `componentSettings.m` file defines how the hardware components of the rig are to be set up. It is read by `BakingTray.settings.readComponentSettings` and created if it does not exist. Instructions for filling in this file are present in the comments of that file. It's **vital** this file is filled in correctly to avoid damage to your system, particularly for the [motion components](/developers/developers/motion-control-classes). For instance, the motion limits of the stages are defined in this file and are used to make it impossible for out of bounds motions to be executed.

The easiest way to fill in these values is to initially set them to max limits of the stages, then put in the water bath and *carefully* find the stage limits. Note these down and edit the component settings file afterwards. You can also change the max and min limits while BakingTray is running by editing properties in, for example, `hBT.xAxis.attachedStage`.

You should first run your stages using the manufacturer's software to familiarise yourself with them. When filling in the component settings file, keep the following in mind:

* The X stage moves left/right as you look at the rig and positive is to the right. Middle of the travel range is 0.
* The Y stage moves front/back as you look at the rig and positive is away from you. Middle of the travel range is 0.
* The Z stage pushes up the sample and positive is up. Fully lowered is 0.
* All motion commands need to be in mm.

For instance, you may find that your X stage moves from "0" to "100" mm with zero on the left. This means the middle of the motion range is 50 mm, not 0 mm, and positive values are to the left not to the right. Thus, the motion commands going to this device will need to be modified. The easiest way of doing this is to create a stage class specific to this stage and use the `transformInputDistance` and `transformOutputDistance` properties to effect the conversion. These properties can also be used to change units. Examples:

* The `haydon43K4U` class which converts between stepper motor steps and mm.

### Controlling the Pockels cell from ScanImage

It is helpful to have the Pockels cell switch on and off with the laser. You can construct a mains relay switchable via an optocoupler and connect a digital line to it. Then under the laser section of the component settings file add the following:

```
laser.pockels.doPockelsPowerControl=true;
laser.pockels.pockelsDAQ='scan';
laser.pockels.pockelsDigitalLine='port0/line0';
```

Obviously replace `scan` with your DAQ name and set the port and line number to values you are using. After this, the Pockels cell and laser will be switched on and off together.

### Startup File

If present, a file named `SETTINGS\startup_bt.m` will run automatically once BakingTray has started. This is done by `BakingTray.m` You may put whatever code you want to execute into this file. It is not sanity checked!


# Calibration


# Basic calibrating procedures

### Theory

BakingTray performs a tile scan over the sample. The individual tiles are later assembled into a single image by [StitchIt](https://github.com/SWC-Advanced-Microscopy/StitchIt). In order to place the tiles accurately and produce a good quality stitched image you will need to ensure that the following are true.

* The X and Y scanners must displace the beam along orthogonal directions.
* The X and Y stages must displace the sample along orthogonal axes.
* The X scanner should move the beam along the direction of motion of the X stage and the Y scanner along the direction of motion of the Y stage.
* The scanning plane (imaging plane) should be parallel with the plane of motion of the X and Y stages.
* The blade must be parallel to the Y stage such that the cuts it produces cause the surface of the sample to remain the same distance from the objective as it is translated in Y.

### Practice

This is what you must do to achieve the above. Read through the whole document before starting.

#### Before starting

You should set the X and Y stages to middle of their travel ranges, mount the water bath, raise it a bit, and manually translate the whole stage assembly until the objective is roughly in the middle of the imagable area. This is just to ensure that you will not run out of travel range on any of the axes.

#### Ensuring the X and Y scanners are orthogonal

Recall that *the X and Y scanners must displace the beam along orthogonal directions and the beam must leave the scanhead at 90 degrees to the angle with which it entered.* The alignment needs to be done once when the microscope is built.

If you have a close-coupled scanner pair you can place it on the table, feed the beam going into it parallel with the table and orthogonal to the scan head box. The scan head should be clamped to the table. Rotate the scanners in their mounts such that the beam exits the scan head parallel with the table and at right angles to the angle at which it came in. You can use the table hole pattern to guide you. Remember to set galvos to their mid-point by feeding in a zero command voltage. Now apply a sinusoidal command voltage to each axis in turn, project the beam onto the wall and ensure the two motion directions are orthogonal.

If the above alignment isn't possible (e.g. you don't want to dismantle your microscope) then you could opt to image [an EM grid](https://github.com/raacampbell/measurePSF) and check whether the grid lines are orthogonal.

If you find the scanners aren't orthogonal to each other then this can only be corrected by altering relative angle of the shafts. Depending on how the scanners are mounted this may or may not be possible. If you can't correct this, it can be done [in software, later](/getting-started/finishing-the-install/calibration/achieving-high-stitching-accuracy).

#### Ensuring the X and Y axes displace the sample along orthogonal directions

The X and Y stages should displace the sample along orthogonal axes. This can be quite hard to measure. It might be best done by imaging with a camera, where you know you are dealing with a square pixel grid. If this step is hard to measure, then skip it for now and only come back to it if you have problems with stitching images that you can't correct.

#### Calibrating the number of microns per pixel

At this point it is helpful to [calibrate the number of microns per pixel](/getting-started/finishing-the-install/calibration/calibrating-the-number-of-microns-per-pixel-with-scanimage) in ScanImage and to ensure that the pixels are square.

#### Ensuring the scan axes are aligned with the stage axes

Recall that *the X scanner should move the beam along the direction of motion of the X stage and the Y scanner along the direction of motion of the Y stage*.

To achieve this, image pollen grains in ScanImage. Right-click on the image window and enable the cross-hairs. Translate a pollen grain along the cross hair of one axis. It should follow it perfectly. If not, rotate the stage assembly about its centre to achieve perfect tracking. You want to get this as accurately as possible. Within a micron if you can.

Then check the other axis. If the scanners and stages are both orthogonal, then you should also get perfect tracking along this axis. If not, as mentioned above, small differences can be corrected at stitching time by introducing a shear to the images.

#### Ensuring the imaging plane is parallel with the motion plane

The scanning plane (imaging plane) should be parallel with the plane of motion of the X and Y stages. You will need to mount the stages on three points of contact with at least two being height adjustable. Image a thin fluorescein layer under a coverslip. Translate the stages two or three mm. The image should not change. If it does, the slide is tilted and you need to re-mount it. Assuming the image plane is not curved, the whole FOV should snap into view at once as you focus through it. If there is field curvature you will likely see the centre appear first and as you move the objective further down you will see a donut. If the stages are aligned with the image plane, the donut should be symmetric.

#### Ensuring the blade is parallel with the Y axis

The blade must be parallel to the Y stage such that the surface of the sample remains the same distance from the objective as it is translated in Y. Adjust the blade angle to achieve this. The easiest way to do this is to make a block of fluorescent agar and cut it and image:

* Cut open a fluorescent marker pen and pour the fluid into a Falcon tube.
* Make up some 5% agar and add a small quantity if your fluorescent dye into it. It will not diffuse out as the dye is composed of small plastic fluorescent particles.
* Cut the agar into a block that is about 10 mm wide by 25 mm long. Glue it to a slide such that you are cutting through the 10 mm width.
* Slice it under the microscope using roughly the thickness and speed you do in practice.
* Find the surface on the left. Zero the Z drive in ScanImage. Then navigate to the right of the agar and see how far off it is.
* You might find it helpeful to take a preview scan of the agar.
* Alter blade angle to compensate for a tilt. Cut again. Measure. Repeat.
* If the agar is not well glued down then it will move and the surface will not be very flat. A loose agar block is very hard to work with.

### Safety first!

The above alignments should be made in the order listed above. Once done, **ensure that no out of bounds motions are possible** by setting the min/max position values for each axis in the `componentSettings.m` file. To do this you should move the axes and manually find how far they can be moved along each axis. Take care with the X direction that move the edge of the bath near to the blade holder: the maximum safe position might vary with Z. This is important to check these limits so the hardware can't be damaged.

#### See also

* [Fine tuning positioning accuracy](/getting-started/finishing-the-install/calibration/fine-tuning-positioning-accuracy)


# Calibrating image size

## Calibrating image size

### Calibrating the number of microns per pixel

BakingTray uses the number of microns per pixel reported by ScanImage to determine where to move the stages. If this number is wrong you will get stitching problems. You will need to perform these steps when you first set up your system and also if you ever have to replace a scanner, since different scanners have slightly different gains. You may also need to repeat these steps for different versions of ScanImage. e.g. sometimes the scanner waveforms change slightly between releases.

There are two related procedures: one for "square" images, where the number of lines per frame and the number of pixels per line are the same. With square images it's pretty easy to just change the number pixels per line to change the resolution. Non-square images are discussed at the end.

### Before you begin

* Acquire bunch of copper EM grids. [1000 mesh (25 micron pitch)](https://www.2spi.com/item/2145c-xa/grids-cu-square/) or [2000 mesh (12.5 micron pitch)](https://www.2spi.com/item/2155c-xa/grids-cu-square/) both work well.
* Carefully place a grid on a glass slide using forceps under a binocular dissection scope.
* Align the square grid such that lines are parallel with the slide edges. This will be useful later on.
* Place a coverslip over the grid and seal the edges with nail varnish such that water can't get in.
* The metal grid will emit visible light when excited with a 2p laser at most wavelengths. e.g. 850 nm will work well.
* Install [measurePSF](https://github.com/SWC-Advanced-Microscopy/measurePSF).

  You will use the provided `Grid2MicsPerPixel` function to measure the exact number of microns per pixel along the rows and columns of your grid images.

### Protocol for calibrating ScanImage with square images

* In the ScanImage CONFIGURATION window check "Pix=Lin" and "Square Pix"
* Copy the scan waveforms to an osciloscope with BNC cables and T-connectors
* Place the grid slide under the objective and obtain an image.
* Orient the EM grid so that the grid axes run parallel to the imaging axes (it's OK to be a couple of degrees out).
* Set zoom to 1
* Choose 512 x 512 pixels

The goal is to obtain the largest FOV possible with the same number of microns per pixel along each axis. When you hit "Focus" you get an image and also you see the amplitude of the scan waveforms. You want a square image of the grid with the resonant mirror control signal at its maximum (probably +5V).

* Confirm the resonant resonant control signal is at the expected maximum value (probably 5V, but check with the spec sheet or manufacturer. e.g. CamTech 4 kHz scanners have a maximum control value <5 V).
* Confirm that the grid looks close to square by eye.
* If the grid does not look near-square then you should stop scanning and edit the number of volts per optical degree for the Y mirror (galvo) in via the ScanImage settings. Editing the value will have an impact immediately, so you can test your new settings right away.

To measure the number of microns per pixel:

* Correct the bidirectional scanning artifact.
* Average on-screen about 10 or 20 frames to get a nice image then stop scanning.
* Run `Grid2MicsPerPixel`, which pulls the data directly from ScanImage. A new window will appear with the grid fitted and the number of microns per pixel in X and Y reported.
* It doesn't matter if not all grid lines are detected, the reported values are based on the median number of pixels between adjacent grid lines.
* Tweak the galvo control signal again if needed.
* The `Grid2MicsPerPixel` allows you to re-import a new image from ScanImage as needed.
* Play with the galvo amplitude parameter until the grid looks square at a zoom of 1 and a maximum resonant mirror control signal. Don't worry if you can not get the image perfectly square. Being out by 1% or 2% is no big deal and we will deal with this later.

### Setting the FoV size in ScanImage

Once the image is square, press the "Apply FOV" in the "Grid2MicsPerPixel" GUI. This button correctly sets the ScanImage property `hSI.objectiveResolution` so that ScanImage reports the number of microns per pixel correctly. The FoV size and the value of `hSI.objectiveResolution` are printed the MATLAB command line.

### Hints:

* Leave the resonant scanner on the whole time so that it settles down.
* Average 10 frames to improve SNR.
* If the galvo waveform exceeds +/-10 V you will get a cryptic error about the output buffer being empty.

### Setting up rectangular images

The following instructions are relevant for systems that have a reduced scan angle along one axis, for instance a 12 kHz resonant scanner. These instructions are not relevant for systems with 8 kHz or 4 kHz resonant scanners. To set up rectangular images that use the whole Y range:

* First perform the steps for square images because you want the number of volts per degree to be equal for two scan axes.
* Now uncheck pix=line in the CONFIGURATION window.
* Set the slow scan multiplier to a number that's as large as possible.

  On our setup this is about 1.9 to 2.1V (it may vary between ScanImage releases due to differences in the galvo waveform shape).

  If you set this value to too large a number you'll get an error about the output buffer being empty.
* Press focus. Note that ScanImage automatically sets the number of lines so that the pixels remain square
* Image the grid and measure.

  You may need to take a small Z stack if not all of the grid is visible over the whole image.

  Alternatively manually average three or four depths at the command line with the right-click and export.
* You should get the same number of microns per pixel as before.

You'll now have rectangular frames with a certain number of microns per pixel. You can go to "File > Save Configuration As" in ScanImage to allow you allow you to re-load this in the future. E.g. you could call your file "rectangle\_078.cfg" for 0.78 micron/pixel images.

## Creating a calibration lookup table for different image sizes

You likely will not always want to use the same resolution for all your samples. In this step you will create a calibration table that allows you to quickly choose the desired image resolution from BakingTray. This is done via a `.yml` file called [frameSizes.yml](https://github.com/SWC-Advanced-Microscopy/BakingTray/blob/master/ExampleConfigFiles/frameSizes.yml). This file contains a series of sections -- one for each resolution -- that are independent of each other. This allows you to, for example, set different `hSI.objectiveResolution` values should that become necessary to get square images with the correct number of microns per pixel. This file is what makes the resolution drop-down menu in BakingTray. Some of the settings in it (such as `affineMat` and `stitchingVoxelSize`) are used by StitchIt when assembling the stitched images. We tweak those values later.

The goal is to end up with a `.yml` file that looks like this:

```
setA:
  objective: nikon16x
  pixelsPerLine: 300
  linesPerFrame: 300
  zoomFactor: 1.0
  nominalMicronsPerPixel: 4.25
  fastMult: 1
  slowMult: 1
  objRes: 51.7
  lensDistort: {rows: 0, cols: 0.03}
  affineMat:
    - [1, 0,  0]
    - [0, 1,  0]
    - [0, 0,  1]
  stitchingVoxelSize: {X: 4.1, Y: 4.39}
setB:
  objective: nikon16x
  pixelsPerLine: 562
  linesPerFrame: 562
  zoomFactor: 1.0
  nominalMicronsPerPixel: 2.2
  fastMult: 1
  slowMult: 1
  objRes: 54.7
  lensDistort: {rows: 0, cols: 0.0}
  affineMat:
    - [1, 0,  0]
    - [0, 1,  0]
    - [0, 0,  1]
  stitchingVoxelSize: {X: 2.23, Y: 2.335}
setC:
  objective: nikon16x
  pixelsPerLine: 750
  linesPerFrame: 750
  zoomFactor: 1.0
  nominalMicronsPerPixel: 1.7
  fastMult: 1
  slowMult: 1
  objRes: 53.44
  lensDistort: {rows: 0, cols: 0.01}
  affineMat:
    - [1, 0,  0]
    - [0, 1,  0]
    - [0, 0,  1]
  stitchingVoxelSize: {X: 1.66, Y: 1.755}
```

If you have linear scanners (galvo/galvo) then you will have two extra fields: the sample rate (`sampRate`) and pixel bin factor (`pixBin`).

To populate the file, do the following:

* Set the number pixels in ScanImage with the help of `hBT.scanner.returnScanSettings` to choose a suitable image size.
* The number lines per frame *must be an even number* or you will get weird illumination artifacts if you do Z stacks..
* Enter the image size and the nominal number of microns per pixel this corresponds to in a settings section.
* Enter the `hSI.objectiveResolution` value in the `objRes` field of the `.yml` file. Use the value obtained above.
* For now set the `stitchingVoxelSize` values to the nominal value. These will be tweaked later.
* Repeat for other desired image resolutions. Typical useful image resolutions can be found [in the user instructions under "Choosing Imaging Settings"](/users/choosing-imaging-settings).

BakingTray will find your file when it starts and add these resolutions to the recipe section in the main view window. You can then select them and the settings will be applied. The method that does this is `hBT.scanner.setImageSize` (a method of `SIBT`), should you want to apply this at the command line. The `hSI.objectiveResolution` is not cached in the ScanImage `.cfg` file.

### You must use an even number of scan lines!

Ensure that the number of scan lines is an even number or you will get a an illumination artifact that looks like this if you have Z stacks and change the laser power with depth:

![](/files/iZgy8NKuB8Dc3dOwZJz4)

What you are seeing is that the higher laser power for the optical plane below this one is happening one line earlier in each tile.


# Achieving high stitching accuracy

Data will be stitched using [StitchIt](https://github.com/SWC-Advanced-Microscopy/StitchIt). StitchIt assembles stitched sections out of individual tiles by placing images according to their position in the image grid and the number of microns per pixel of the images. If the number of microns per pixel is not accurate, the tile placement will also not be accurate. Furthermore, StitchIt will assume images are undistorted and that the stage motions are perfectly in line with the scan axes. Deviations from the above will cause imperfections in stitching accuracy. These instructions explain how to create tweaked microns per pixel values and correct for any image distortion prior to stitching.

It assumed that you have already:

* [Calibrated the number of microns per pixel](https://github.com/SWC-Advanced-Microscopy/BakingTray/wiki/Calibrating-the-number-of-microns-per-pixel-with-ScanImage).
* [Aligned the scanners and stages correctly](https://github.com/SWC-Advanced-Microscopy/BakingTray/wiki/Basic-calibrating-procedures) and you should already know if imaging a grid results in non-square grid lines.

You will need to install StitchIt before proceeding.

## Measuring and correcting for image distortion

### Note before you start

The following instructions explain how to use an EM grid to measure barrel/pincushion distortion and correct for independently along the two scan axes. It is not completely clear at present whether this is necessary. You can go through the following instructions, determine correction values, then try them out. Be open to the possibility that you might get better stitching accuracy without this correction applied: try both with and without.

### Measuring distortion

Acquire a uniform EM grid. Part number 2145C from [2spi](https://github.com/raacampbell/bakingtray_docs/tree/aa53947efba18b64e6d15320116ffccf214adfb7/getting_started/finishing_the_installation/calibration/www.2spi.com/category/grids/README.md) works well. This grid has a pitch of 25 microns, a hole width of 19 microns, and a bar width of 6 microns. Place the grid on a slide and seal with a coverslip and nail varnish. Image the grid at low power: the copper will auto-fluoresce under a 2-photon laser. Align the grid with the image axes. Use a higher image resolution (1 micron per pixel should do). This will make easiest to see any barrel or pincushion distortion. Inspect the image. If you see noticeable distortion then do the following:

1\) Right click on the channel window and copy the image to the base workspace. 2) The `stitchit.tools.lensdistort` command to correct for the distortion. e.g. see what `imagesc(stitchit.tools.lensdistort(ImageData,0.2))` looks like. You will need to experiment and see the function help: note that `k` can be vector.

Once you have settings that look reasonable to the eye, note down the values.

Modify the scan settings file so it contains these numbers under a field called `lensDistort`. You will also want to add the fields `affineMat` and `stitchingVoxelSize` to handle shear and to get exact numbers for the stitching accuracy. **File an issue if you need help with this now. Docs to come.**

```
 setB:
  objective: nikon16x
  pixelsPerLine: 750
  linesPerFrame: 750
  zoomFactor: 1.0
  nominalMicronsPerPixel: 1.667
  fastMult: 1
  slowMult: 1
  objRes: 53.44
  lensDistort: {rows: 0, cols: 0.03}
  affineMat: 
    - [1, -0.014,   0]
    - [0.0,    1,   0]
    - [0,      0,   1]
  stitchingVoxelSize: {X: 0.673, Y: 0.658}
```

You will likely need to repeat the measurements for different zoom values but not for different image resolutions.

## Tweaking the number of microns per pixel

Acquire a small tile of scan of a sample with structure. Agar with dissolved fluorescent marker pen will do. You can acquire just one small 9 by 9 grid with one section and one optical plane. Make sure you uncheck the boxes to turn off the laser and to slice. The laser box you will have to uncheck ***after*** the acquisition starts. Use imaging settings where you have entered a `lensDistort` value in the `yml` if needed. Once the acquisition is done you can verify that indeed you can see the `lensDistort` value in the recipe yml file. Stitch the data with chessboard stitching. e.g.

```
stitchSection([1,1],2,'chessboard',1,'overwrite',1)
```

Visualise and look at the overlap regions. If you see too much overlap you need to decrease the number of microns per pixel. Too little overlap means you need to increase it. The settings you need to change are:

```
StitchingParameters: 
  VoxelSize: {X: 1.2212, Y: 1.221}
```

Play with one at a time to see which affects which axis.

If you continue to see offsets that seem like sideways offsets then you can add an affine term. e.g. these parameters will add some distortion along the columns and perform a skew along one axis.

```
StitchingParameters:
  VoxelSize: {X: 1.654, Y: 1.615}
  lensDistort: {rows: 0.0, cols: 0.03}
  affineMat:
  - [1.0, -0.011, 0.0]
  - [0.0, 1.0, 0.0]
  - [0.0, 0.0, 1.0]
```

Save the recipe and re-stitch after each attempt.

This affine matrix is equivalent to doing `imrotate` by -0.75 degrees:

```
  - [0.9999, -0.0131, 0.0]
  - [0.0131, 0.9999,  0.0]
  - [0.0,      0.0,   1.0]
```

This is because:

```
>> cos(deg2rad(-0.75))
ans =
    0.9999

>> sin(deg2rad(-0.75))   
ans =
   -0.0131
```


# Fine-tuning positioning accuracy

The number of microns per pixel in BakingTray is used to move the stage to the correct positions in order to perform a tile scan with the desired overlap between adjacent tiles. The number of microns per pixel is also used by [StitchIt](https://github.com/SWC-Advanced-Microscopy/StitchIt) to assemble the image tiles into a stitched image. i.e. The tiles aren't "registered into place". They are positioned where they ought to be in theory. We find this works well so long as the system is [aligned correctly](https://github.com/SWC-Advanced-Microscopy/BakingTray/wiki/Basic-calibrating-procedures) and the number of microns per pixel is [accurately measured](https://github.com/SWC-Advanced-Microscopy/BakingTray/wiki/Calibrating-the-number-of-microns-per-pixel-with-ScanImage).

After conducting the above procedures you may still see errors in tile placement. These errors should be due to the following sources:

* Scanners being not quite orthogonal.
* Stages being not quite aligned with the scan axes.
* The number of microns per pixel being slightly wrong.
* Stage positioning errors.

The last error is will be random but with high quality PI stages that are running properly it will be *very* small. So small, in fact, that for most situations we stitch using the theoretical stage positions and lose no accuracy compared to using the real stage positions.

Tile position errors should therefore be due to remaining factors, should be constant across the sample. Furthermore, these errors will be more apparent for larger tiles. Why is this? Consider tile *A* and the tile to the right of it, tile *B*. A structure on the right edge of tile *A* will be on the left edge of tile *B*. Imagine that the only error we have is due to the stages and scanners being slightly non-square with respect to each other. Structures at tile edges will appear shifted (non-contiguous) by an amount that is proportional to this misalignment. For a given angular misalignment, the measured offset at the edge will increase with FOV. Similarly, if the number of microns per pixel is off by 1 nm this will translate into a 1 micron error over 1000 pixels but only a half micron error over 500 pixels. So for a fixed image resolution, larger fields of view will be more prone to misalignment.

## Minimising the above issues

To reduce errors arising from the number of microns per pixel being slightly off, you can tweak this value in the sample's recipe file. Acquire one section of a small area (e.g. 5x5 tiles) where there are a lot of features. Ensure [StitchIt](https://github.com/SainsburyWellcomeCentre/StitchIt) is installed and stitch the data with the "chessboard" feature: (e.g. `stitchSection([1,1],3,'Chessboard',true)`) and visualise in Icy or Fiji. Look at the tile overlap regions.

Can they be improved? Likely yes. To do this, go into the recipe file and modify the `X` and `Y` values on the line that looks like: `VoxelSize: {X: 1.322, Y: 1.322}`. This is the line just after `StitchingParameters`. Change one at a time to see the effect. Then re-stitch. If you have no other sources of error, it's possible to get near-perfect stitching this way. Once happy, you can go back to the `frameSizes.yml` file and update it. BakingTray can be made to re-read this file using `hBT.scanner.readFrameSizeSettings`. You can confirm this worked by looking in `hBT.scanner.frameSizeSettings(x).stitchingVoxelSize` You can then go back and tweak the objective resolution in ScanImage to reflect this new value so you don't need to tweak it each time.

The following image shows the effect of fine-tuning stitching accuracy. On the left is the stitching accuracy using the number of microns per pixel obtained by measuring with a grid (1.316 microns per pixel) on the right is the with this number manually over-ridden to 1.323 microns per pixel. So that's a tiny difference: only 7 nm per pixel! In this case the images shown have been downsampled such that 1 pixel is 2.632 microns.

![](/files/36qSbo4S68TodBIAABP9)

Once you have the more accurate number for the microns per pixel, you could try running `Grid2MicsPerPixel` using a grid pitch that produces this number. For example, our grid will reliably produce 1.316 microns per pixel using a certain set of scan settings. However, we found stitching accuracy was better at 1.323. So we can instead do `Grid2MicsPerPixel(ImageData,'GridPitch',25.125)`, which produces a microns per pixel value of 1.322. From now on, using this tweaked value for the number of microns per pixel (e.g. when measuring for different objectives or image resolutions) should produce a slightly more accurate value.

## Handling other sources of error

If the above does not work, then probably there is a rotation issue at play or possibly barrel/pincushion distortion. Both of these can be handled. StitchIt includes a function called [lensdistort](https://github.com/raacampbell/lensdistort) which will deal with different sorts of distortion along the two axes if needed. The best way to assess this is to image an EM grid and see how much correction is needed. You can use the above tool directly on the image. Then enter the distortion parameters into the `lensDistort` section of `frameSizes.yml`. In addition to this, affine transformations are supported and this includes the option of correcting rotation. Do this by editing `affineMat` in the recipe file (for testing) then copy parameters to `frameSizes.yml`. i.e. No transformation would be:

```
1 0 0
0 1 0
0 0 1
```

And you can rotate tiles by doing:

```
1 0.15 0
0  1   0
0  0   1
```

It's just a normal affine matrix. Google for more.


# Stitching tweak walkthrough

Tweaking BakingTray and StitchIt for high stitching accuracy

This page is a walkthrough explaining how to improving stitching accuracy using BakingTray and StitchIt. It's description of a real session during which a mistake a was made that then needed correction.

## First look

We begin by stitching a section and looking at it:

```
>> IM=chessboardStitch([75,1],2); %Slow for larger datasets 
>> exploreChessboard(IM,4000) %Slow for larger datasets
```

The fact the red tile is above the green on one side and below on the other tells me there is a rotation problem.

![](/files/I7THiFyLfPWpuQybsPe7)

The bidirectional scanning correction in ScanImage wasn’t set quite right. We can fix this post- hoc, although the correction is a bit hackish at the moment.

![](/files/jd69aowvohMiycZqU76n)

Indeed, upon zooming in to an area with obvious features the microns per pixel is very far off:

Indeed, microns per pixel is very far off:

![](/files/ly7FR7DEoRdOe4P6avat)

## First tweak

What are the values?

```
>> IM.params.voxelSize
ans =
struct with fields:
X: 0.8060 Y: 0.8060 Z: 5
```

We know it needs to be a larger number so the tiles end up overlapping more. Let’s try just one axis first:

```
>> IM(2)=IM; %copy
>> IM(2).params.voxelSize.Y=0.82; %New value
>> IM(2)=chessboardStitch([75,1],2,IM(2).params); %re-stitch
>> exploreChessboard(IM,4000) %Compare new and previous versions
```

Note that now `IM` has a length of 2. When we run `exploreChessboard` with `IM` having a length of 2, we see the two images side by side:

![](/files/GZvXGp0SZNHbUE8WwQll)

And if we zoom in:

![](/files/R7qRJ0HJ48bLsnAQZf74)

## Adding a tile rotation

It looks much closer. They are offset because of the rotation we noted earlier, but we’ll fix that later. Let’s do the other axis too.

```
>> IM(2).params.voxelSize.X=0.815; %New value
>> IM(2)=chessboardStitch([75,1],2,IM(2).params); %re-stitch
>> exploreChessboard(IM,4000) %Compare new and original versions
```

Closer. But’ll play with rotation before going back to mics per pixel. \[**NOTE: AT THIS POINT I WAS ASSUMING THAT THE GREEN FIBRE AT THE UPPER OVERLAP REGION IS PART OF THE RED BELOW IT. TURNS OUT LATER THAT IT WASN’T, BUT I DIDN’T REALISE THAT HERE**]

![](/files/FQAyRcfYuA4djCBtZ5iU)

To make this easier I will use affineMatGen that (in this case) is in `BakingTray`. I don’t have this function in my path on my desktop PC so I add it now. In future this file should be in stitchIt,

```
>> ls ~/work/Anatomy/code/bakingtray/code/BTresources/
LimitFigSize.m TileStepSize.m plotboxpos.m previewFilesToStack.m NumTiles.m affineMatGen.m prettyTime.m

>> addpath('~/work/Anatomy/code/bakingtray/code/BTresources/')
```

Create a matrix with a small rotation and add it to IM(2).params:

```
>> affineMatGen('rot',-0.3)
- [0.999986, -0.005236, 0.0] - [0.005236, 0.999986, 0.0] - [0.0, 0.0, 1.0]
>> A=affineMatGen('rot',-0.3) A=
1.0000 -0.0052 0 0.0052 1.0000 0 0 0 1.0000
>> IM(2).params.affineMat ans =
[]
>> IM(2).params.affineMat=A;
```

Let’s see what that does. Stitch and explore as before. In the area we were looking at before, stuff is better:

![](/files/BNnNT1w7Oj91zPHOHbZV)

But I really care about the sample edges right now, as rotations are really obvious there. Especially along the dorsal and ventral surfaces. I therefore re-explore with a lower threshold and look there.

```
>> exploreChessboard(IM,2000)
```

![](/files/6ZM78rtyASXRQz9EnWyu)

We can do better. There is still rotation and it looks like we didn’t over-compensate. Let’s start fine-tweaking by comparing the above, nicer, version to a new version:

```
>> IM(3)=IM(2); %Copy again
>> A=affineMatGen('rot',-0.35);
>> IM(3).params.affineMat=A;
>> IM(3)=chessboardStitch([75,1],2,IM(3).params);
>> exploreChessboard(IM(2:3),2000)
```

That wasn’t enough \[NOT SHOWN] so repeat with more rotation:

```
>> A=affineMatGen('rot',-0.45);
>> IM(3).params.affineMat=A;
>> IM(3)=chessboardStitch([75,1],2,IM(3).params); exploreChessboard(IM(2:3),2000)
```

That still wasn’t enough \[NOT SHOWN] so repeat with more rotation:

```
>> IM(3).params.affineMat=affineMatGen('rot',-0.5);
>> IM(3)=chessboardStitch([75,1],2,IM(3).params); exploreChessboard(IM(2:3),2000)
```

Finally this is much better:

![](/files/FRZ1Ukb7GKWupeFrHjis)

Certainly not perfect. Never is perfect. But very much better. Try another 0.05 degrees and compare what we just did to that:

```
>> IM(2)=IM(3); %Replace second with third to get a yet finer comparison
>> IM(3).params.affineMat=affineMatGen('rot',-0.55); IM(3)=chessboardStitch([75,1], 2,IM(3).params); exploreChessboard(IM(2:3),2000)
```

This is again slightly better \[NOT SHOWN]. We can leave the rotation for now and go back and explore the dataset more carefully, considering microns per pixel again.

```
>> exploreChessboard(IM(2:3),4000) %Change threshold to higher value again
```

The region we first concentrated on looks better than before the rotation correction:

![](/files/w2wrJ6dvubvNSTUyfdXC)

## Exploring Y microns/pixel

But maybe microns per pixel in Y still needs tweaking? We need to pan around the sample to see what’s going on elsewhere. Can’t base everything on just one area. I see this, which I don’t like. This is miles out and can only be explained by stage motion errors, or the sample shifting, or a tilted focal plane, or the X value still being wrong. Tilted focal plane is unlikely to have such a big effect, though. \[**NOTE: THIS IS WHEN I STARTED TO QUESTION WHAT THAT FIBRE WAS AT THE START**]

![](/files/7dYpzg9f0CtVWTZktPes)

I also see this, which looks very much like tilted focal plane, but that’s an error along the other scan axis.

![](/files/ZKrFw0O88uC3Ve0901Jb)

Let’s go with my X value being wrong. Let’s look around for other evidence of this.

![](/files/5fWjeyDmYlR71GaiKwCh)

## Looking at the EM grid image for this system

Yes, it looks like that’s what’s happening. Note that I’m paying attention to regions near the middle of the tiles. Looking at the grid image quickly in Fiji for this microscope I see this:

![](/files/JZtAcPX9ew7f9rriRoaK)

I had to rotate tiles 90 degrees to stitch, so the left and right edges are the ones I care about. Note there is pincushion distortion there. The other two axes seem good. Let’s correct the grid image first. The X value was set based upon pixels near a corner, so we’ll not touch it yet. I also note that this grid image has a bidirectional scanning artefact too.

Let’s have a fiddle:

```
>> imagesc(G(:,:,1)) %Loaded into MATLAB now
>> caxis([0,5000]), axis square
```

![](/files/DVMQ8xi8AEZyLOHe77rY)

```
%Play a bit until we get this
>> imagesc(stitchit.tools.lensdistort(G(:,:,1),[0.04,0.0]))
```

![](/files/l5K8zhY2rQdFTyGiERv5)

```
>> IM(3).params.lensDistort.cols=rows; %We want to work along the rows
>> IM(3)=chessboardStitch([75,1],2,IM(3).params); exploreChessboard(IM(2:3),2000)
```

This looks like we’ve over-compensated, but we know that the grid image looks square.

![](/files/EPDqjSfLK8iUk1PDvHBP)

## Go back and tweak X

So we need to tweak X. This is why what I should have done was fix the barrel distortion before doing anything else.

```
>> IM(3).params.voxelSize
X: 0.8150 Y: 0.8200 Z: 5
>> IM(3).params.voxelSize.X=0.8;
>> IM(3)=chessboardStitch([75,1],2,IM(3).params); exploreChessboard(IM(2:3),2000)
```

Iterate a bit until stuff looks good. We cycle through:

```
>> IM(3).params.voxelSize.X=0.805;
>> IM(3).params.voxelSize.X=0.8075;
```

And now we see:

![](/files/43JATW3Cp12w1D7Ct9sV)

That stuff that was previously bad is now good. Pan around a bit. It all looks about as good as expected considering the tilt in the focal plane. This can only be corrected by tilting the stage. The only other option would be affine transformation in Z, but that would require very dense sampling in Z which we don’t typically do.

## Commit to recipe file

In this case we want to tweak an already acquired sample so we commit our changes to the recipe file:

![](/files/EefpFvSgw1VUGC4VAVI4)

It would also be a good idea to add these changes to the [frameSizes settings](https://github.com/raacampbell/bakingtray_docs/tree/master/getting_started/finishing_the_installation/calibration/broken-reference/README.md) file in `BakingTray` so all future samples have these good parameters saved with them.

```
% stitching from this file produces the good stuff
>>IMfinal=chessboardStitch([75,1],2);
>> exploreChessboard(IMfinal,4000)
```

![](/files/0UL1UQwiwSb5SnqeFf2U)


# Stitching data


# Introduction

Serial section 2-photon is a microscopy technique for unattended imaging whole organs at high resolution. See the [gallery](https://bakingtray.mouse.vision/gallery) for example data.

## How does serial section 2-photon work?

A sample is embedded in agar, glued to a slide, mounted in a water bath, and placed under the microscope. A vibratome associated with the microscope exposes the top of the sample block. The microscope performs a tile scan over the exposed sample surface then slices a thin section off the block. The microscope alternates between tile scanning and imaging until the whole sample has been acquired. Physical sections are taken approximately every 50 microns and optical sectioning is possible to allow for finer resolution in z. The slices sink down to the bottom of the water bath and are usually discarded once acquisition is complete.

## What sort of samples are suitable?

Any sample that can be embedded in agar, cut on a vibratome, and contains a fluorescent signal can be imaged. Fixed tissue exhibits rich autofluorescence so label-free structural imaging is possible. Imaging of a wide range of fluorophores is, of course, also possible. The sample should ideally be brightly labeled to allow for short integration times and therefore faster imaging. Typical use cases that work well include counting labeled somata, mapping dye-labeled electrode tracks in brains, tracing bulk fibre projections in brains. Higher resolution scenarios, such as brain-wide tracing of individual axons is possible but very challenging.

## How does serial section imaging compare to conventional approaches?

Datasets created by automated microscopy techniques can potentially be very large and so will usually require automated analysis techniques in order to extract meaning. It becomes particularly important to select imaging resolutions that are appropriate for the question at hand otherwise dataset size can quickly enter the TB range and acquisitions stretch into multiple days. Parameters such as voxel size and integration time should be carefully chosen to be adequate for the downstream analysis pipeline and not over-sampled. Often a quality that is perfectly adequate seems noisy or low resolution to those more familiar with confocal microscopy or even automated slide scanners.


# Sample preparation

A major advantage of serial section microscopy is that it generates 3D images that are easy to register to a standard atlas and are particularly amenable to automated analyses. However, to take advantage of this the samples must be well prepared, undamaged, and well mounted. Samples that are damaged, full of blood, or mounted at extreme angles will be hard or impossible to work with later. Take sample preparation seriously!

## Perfusion

### General Perfusion

* Perfuse as normal in 4% PFA. Do not drop-fix. Do not use old PFA: opened PFA bottles can be kept for up to 3 months in the fridge.
* Take **great care** removing the brain from the skull. Aim for zero damage. Use a dissection scope if it helps. Keep the olfactory bulbs and the cerebellum.
* If you see dura adhering to the surface, remove it with care.
* Post-fix overnight in 4% PFA at 4 degrees C. This is more important for rat brains: these may need two days.
* Transfer to 1x PBS. Brains should sit in 1x PBS at least overnight before imaging as the higher osmolarity of 4% PFA will cause brains to expand once the enter the imaging buffer.
* Sucrose is not involved: we aren't using a cryostat.
* Longer term storage (months) is not encouraged because brains deform over time. If necessary, however, use 0.01% azide and label as such. Do not use higher azide concentration: that stuff is really dangerous.

### Rat perfusion tips

For producing rat brains with all blood removed try the following:

1. Use pentobarbital for overdose if you are not using it already, and use enough to knock it out in around 30s. About 2-3 ml per animal.
2. Time between pento injection and starting perfusion should be as low as possible (under a minute). You will need a fast and precise dissection.
3. Perfuse with about 150 ml of PBS or PB over 2-3 minutes followed by 200 ml of PFA for 4-5 minutes. The idea is to have enough flow at a good enough speed.

The basic cause of blood is more time spent after Pento injection and before start of perfusate flow leads to internal blood clotting (more viscous with time), and becomes difficult to push out especially in the finer vessels and capillaries. As for mouse brains, rat brains should sit in 1x PBS at least overnight before imaging as the higher osmolarity of 4% PFA will cause brains to expand once the enter the imaging buffer.

## Protocols

* [50 mM PB slicing buffer](https://www.protocols.io/view/brainsaw-50-mm-ph-7-4-pb-slicing-buffer-q26g714r3gwz)
* [5% agar stock solution](https://www.protocols.io/view/brainsaw-agar-stock-solution-ewov19nm7lr2)
* [single brain mounting protocol](https://www.protocols.io/view/embedding-one-brain-for-serial-section-imaging-ddcx22xn)
* [Four brain embedding protocol](https://www.protocols.io/view/embedding-four-brains-for-serial-section-imaging-ddck22uw)


# User Guide


# Starting BakingTray

If BakingTray is not already running, follow these instructions to start it. Start MATLAB if necessary. Run `BakingTray` at the MATLAB command line. BakingTray uses ScanImage to acquire image data and it will attempt to start it first. When the ScanImage start GUI appears you should click "Start ScanImage"

![Starting ScanImage](/files/-MAWHVHjTA5YdiDIuu0X)

Note we are loading a USR file with custom settings for our system. Once started, the USR file configures ScanImage to look something like this (click for full-size version) once started:

![](/files/-MAW_G2n417n8ud0qhTG)

After ScanImage has opened, BakingTray will start automatically.

![](/files/-MAWHVHnhn8JlW597K7Y)


# Step 0: Loading the sample

If necessary, [start ScanImage and BakingTray](/users/user_guide/step_01_starting-bakingtray). The instructions over the following pages are [summarized as a checklist](/users/user_guide/checklist).

### Turn off the PMTs

{% hint style="warning" %}
The PMTs are DELICATE and will be DAMAGED PERMANENTLY if exposed to room light when they are powered on. Turn off the PMT power box before proceeding with sample set up. Make sure you always close the microscope enclosure and turn off its lights before you turn on the PMTs.
{% endhint %}

### Turn on the laser

![](/files/57jnnrnIAqnFbt4q7OMj)

Hit the "Laser" button in the main view then press "Turn On" on the laser window. After hitting this button the text switches to "Turn Off", as shown above. The power will increase slowly and eventually the modelock indicator will turn from red to green. You can open the shutter now too: there is a second shutter on the path so there is no risk. Select the [correct wavelength](/users/choosing-wavelength) for this acquisition.

### Remove the previous sample (if present)

If it is not already visible, open the "Prepare" GUI by clicking on "Prepare Sample", as shown below.

![](/files/-MAWHV5cfiaB-utyuT92)

Enter "0" in the "Z" text entry box of the Prepare GUI to lower the water bath using the Z stage. Hose down the objective with distilled water as shown below, then clean the tip with a piece of folded lens paper. Be gentle: don't push against the tip of the objective with the lens paper. If you do not know how to do this, find an experienced person to show you.

![](/files/XMFQe8kYkkgqtXzifxEh)

Unscrew the blade holder with the large black thumbscrew and remove it from the vibratome. Take care not to cut yourself. Unscrew the blade retaining screw (shown below). Do not loosen the side screws! Remove the blade and dispose in the sharps bin.

![Remove the blade by loosening the top screw. Do NOT loosen the side screws.](/files/bTW5TURFGjuAQDvpNW4j)

Confirm whether the system requires the objective to be raised for the bath to slide out. Then slide out the bath. Dispose of brain slices as appropriate.

### Start a new sample

Select Sample -> New from the menu. This will reset the recipe and turn on the resonant scanner (if present). NOTE: you do "New Sample" with the previous sample in place you will have to manually increase the number of sections to slice.

![](/files/-MWdEHrK4s1jNpjkHYhk)

### Clamp the new sample into the water bath

Unscrew the clamp holding the slide in and dispose of the slide in the sharps bin. Insert the new slide with the sample into the clamp. Note there is a stop on the slide clamp to keep the slide from protruding over the edge of the platform. The agar block should be placed adjacent to this stop. In the following image, the stop is a round headed screw.

![Slide placed into the sample holder pedestal](/files/gVtwuLtBDylCMvjMaJTK)

Push the metal clamp over the slide and tighten it down. Do this carefully: first turn one side until it just starts to tighten and repeat on the other side. Then return to the first screw and tighten until finger tight. Repeat with the other. The slide should now be tight.

![Clamp in place and tightened](/files/sIAIbiUCQxV3ndjClhNI)

{% hint style="warning" %}
The microscope is set up such that it is not possible for any hardware elements to collide, however this does assume that the clamp is not angled upwards once secured.
{% endhint %}

### Place the water bath onto the stage

Gently and carefully place the water bath onto the stage. Push it all the way back into the holder and tighten the retaining screw(s) until just finger tight.

### Put in a new blade

Insert a new blade into the holder and tighten until a little beyond finger tight. Thread the blade holder thumbscrew through the holder and screw the holder to the vibratome. Whilst you tighten, push down on the blade holder with two fingers as shown below.

![Push down on the blade holder as shown whilst tightening the thumbscrew](/files/7V43txR1N9ykGGpgaZkm)

{% hint style="warning" %}
Pushing down on the blade holder is a critical step. This ensures the holder is secured at a reproducible angle with respect to the Y stage. Not doing this can lead to sectioning artifacts.
{% endhint %}


# Step 1: Setting imaging parameters

#### Select a directory to which data will be saved

![](/files/t6kwmN2hM9HmmmwvBwcg)

Hit the "Dir" button to select a directory where data will be saved. **Do not use spaces in the directory name.** Your current working directory in MATLAB will be unchanged. The Sample ID (see below) is automatically set to be the same as the directory name, but this can be changed in the next step.

#### Edit the recipe

![](/files/-MAW_G2w5-TaLEdTVbbR)

The "recipe" describes the acquisition parameters, edit to your needs. Here we have changed:

* *Tile Size* describes the [imaging resolution](/users/choosing-imaging-settings).
* *Scan Mode* describes how the tiled acquisition will be performed. In "Manual ROI" mode you draw a ROI over the sample and this same area is imaged in all sections. In "auto-ROI" the sample is automatically identified and the ROI re-calculated after each section.
* *Sample ID* is a string that defines the sample name and is used for file naming. A default is provided if you enter nothing.
* *Slice Thickness* is the physical section thickness in mm. i.e. how much is sliced off the block each time. Here this is 40 microns, [which is a reasonable compromise value](https://bakingtray.mouse.vision/users/choosing-imaging-settings).
* *Num Optical Planes* defines the number of optical planes within each section. Here this is 2, meaning 2 equally spaced optical planes imaged within each physical section. The separation between these is listed in the text above the recipe: here 20 microns.
* *Num Sections* is the number of sections we will cut over the whole acquisition. Here this is 275 sections, with equates to 11.0 mm of imaged tissue (see text above recipe entry boxes). This is the number of sections multiplied by the thickness of each section. The number of allowed sections is automatically capped based upon the current remaining travel range of the z-stage.
* *Cut speed* defines how fast the blade travels through the sample in mm/s

You may image multiple samples at once, but all must share the same acquisition parameters.

The parameters at the bottom are advanced settings that you likely do not need to ever alter.

#### Select the image resolution

![](/files/-MAWQOT9QNH9n4ldUHd6)

The resolution of the acquisition determines the number of microns per pixel. You should use the pop-up menu shown above to select from one of the pre-defined resolution settings. It is important to [choose the correct resolution](/users/choosing-imaging-settings) for addressing your question. Usually you need a lower resolution than you think: ask if you are unsure about this! Once you have done this, you will see that the image size in ScanImage and Tile Size in BakingTray have updated:

![](/files/-MAW_G2y9Qqu1SfCgvth)

#### Frame averaging

If you expect the SNR to be low, you might choose to average frames to improve image quality. For resonant scanning, this is achieved by altering the Frame Average number in the ScanImage Image Controls window (below). You may alter this number once the acquisition started but you have to wait until the sample is being sliced to do so. For linear scanning you should instead alter the pixel dwell time in the ScanImage Configuration Controls.

![](/files/-MNecRiBtOdFKdl6YC-L)

{% hint style="info" %}
Do not become too preoccupied with the image quality of the autofluorescence. The main use of the autofluorescence signal is for registering to a standard atlas and this is achieved using a downsampled image stack, which is heavily averaged when it is constructed. The intensity of the fluorophore signal is substantially higher than the autofluorescence, so in most cases no averaging is needed for downstream analyses to be successful. For more information on frame averaging and examples of how effective it is see [Choosing a Resolution](/users/choosing-imaging-settings).
{% endhint %}

{% hint style="info" %}
As a rule of thumb, a microscope with an >1 mm FOV can image six brains in under 24 hours at a resolution suitable for tracing bulk projections and electrode tracks. It will image four brains at cell counting resolution in under 24 hours, assuming no averaging. Avoid averaging with 4 cellfinder brains or imaging >4 cellfinder brains at once. See [Choosing a Resolution](/users/choosing-imaging-settings) or ask for more information.
{% endhint %}

#### The ScanImage CHANNELS window

Select which channels are to be saved using the "Save" checkboxes in the [ScanImage Channels window](http://scanimage.vidriotechnologies.com/display/SI2019/Channels). Select which channels are to be displayed on-screen during acquisition using the "Display" checkboxes. These settings can not be changed once acquisition commences. If you selected multiple channels to display, all but one will be automatically disabled after the first section is complete for performance reasons.

Note that a friendly name for each channel is provided in the PMT GUI, as shown below. In the case of the example system shown, Channel 2 is "green".

![Channel selection and PMT windows in ScanImage Basic](/files/rhwNh5ILAP7GWU7gQznZ)

![Channel selection and PMT windows in ScanImage 5.6](/files/-MNdHWLcVNfF91MXwjGd)


# Step 2: Preparing the sample

#### Insert the sample

The sample is loaded into the microscope in a water bath filled with low osmolarity phosphate buffer. 50 mM room temperature PB works well. PBS and/or higher concentration buffer just create a lot of annoying salt deposits.

Brains are best loaded bulb down and with the ventral side facing the blade. The blade is affixed to the blade holder (we use a new blade every 200 to 300 sections).

#### Open the prepare GUI

![](/files/-MAWHV5cfiaB-utyuT92)

In case the prepare GUI is not already open, hit the "Prepare Sample" button on the main view to open the Prepare GUI, which is used for sample trimming and moving the stages manually.

The sample can be moved by editing the text entry boxes, using the large and small motion step arrows, or keyboard shortcuts. More on this below. Trimming of the sample is achieved using the slicing buttons at the bottom of the window.

#### Set the blade position

The goal here is to move the sample so that its top right edge (see below) is next to the blade. This informs the software of the correct location to start cutting. The gap between the blade tip and the agar block can be small (one mm or so is fine) if the edge of the agar on the blade side is straight and vertical. The smaller the gap, the less time is wasted cutting nothing.

![The blade positioned next to the agar block, ready to take the first slice.](/files/1BwiExDybZaHBvRRY6Kv)

It is easiest to coarsely move the sample using X/Y/Z text entry boxes for stage position, before transitioning keyboard shortcuts for the fine positioning.

![Keyboard shortcuts for moving the stages. Hold SHIFT for large motion steps.](/files/L4dImvsranZ4CIEByTR6)

* WASD for X/Y (W and S for Y; A and D for X).
* To move the stage up use either Q and E or use R and F. Q and R moves up. E and F moves down.
* Hold shift for large motion steps. Step sizes are those indicated in the GUI.

To use the keyboard shortcuts, the Prepare GUI must have mouse focus but you should not have clicked on a text edit box, or you will end up typing in it. Hold shift for large motions. You should position the sample such that it's about one mm away from the blade and the blade tip is near the top of the sample in Z. Then hit "Set blade position" to store this position:

![](/files/-MAW_G4BvzD559r-H3xZ)

BakingTray now knows where the blade is with respect to the sample. You can edit this position manually using the edit box (highlighted in yellow, above).

Pressing "Set blade position" button also updates the "Cut Size" (arrowed, above), which is the number of mm the blade moves through the sample whilst cutting. This number should be should be sufficient for the blade to get through sample and proceed a little further over the other side so the cut section clears the sample block. You can edit the Cut Size value at any time.

#### Take the first slice

![](/files/-MAWK6RqePuDER0WgfQO)

Hit the "Slice once" button to take one section. The system will start cutting and the button text becomes red and says "Slicing". You may stop the procedure at any time by pressing "STOP SLICING". The slice is taken at the starting point you defined above and at the speed listed in the Prepare GUI (above). The block will be moved upwards by the thickness value in the Prepare GUI\_ (not the main GUI) and cut at the speed listed in the

{% hint style="info" %}
The thickness of the first cut depends on how far below the sample surface you placed the blade in the previous step. i.e. if the blade is 2 mm below the agar surface, the first slice will be 2 mm thick. If you think the first slice might be too thick (e.g. over about half a mm) then set the cut speed to something slow, such as 0.2 mm/s. If you cut a thick section too fast the agar block can come unstuck.
{% endhint %}

Confirm that the blade proceeds 2 or 3 mm beyond the edge of the agar block and edit the Cut Size if it does not.

{% hint style="info" %}
User-initiated Z motions are blocked by the GUI after the first cut has been made. This is to avoid accidentally altering slice thickness. You can override this by unchecking the Z Lock checkbox in the prepare GUI.
{% endhint %}

#### Approach the imaging depth

You may wish to trim away some agar or maybe part of you sample before you reach a location where you want to start imaging. e.g. You may choose to slice through most of the cerebellum before starting. Here we do this by asking the Prepare GUI to take 3 slices of 350 microns (0.35 mm) each by pressing the highlighted button. You can change how many slices it will take using the edit box and you can stop at any time with the "STOP SLICING" button.

![](/files/-MAWK6Rr9Jf1Ql9XIVhG)

We are cutting these slices fairly slowly at 0.3 mm/s. Speeds of up to about 0.50 mm/s are safe to use for acquisition.

Even if you do not want to slice off a lot of tissue, take at least once slice that is about 100 to 200 microns thick after your initial slice. This calibrates the microscope and ensures that the slice thickness value in the Prepare GUI is close to what the system is actually doing (this will not be the case after the first slice for the reasons explained above).

#### Cutting thin slices

You can not jump straight from thick slices all the way down to the thin slices you will use for imaging. If you do this, the vibratome may not cut at a consistent thickness: it could alternate between cutting thick and thin slices. Once you are ready to image press the "Auto-Trim" button. This will take a series of increasingly thin sections culminating with three at the target (imaging) section thickness and speed. For more information on choosing a cutting thickness see "[Choosing imaging settings](/users/choosing-imaging-settings)".

![](/files/bEQg2S7ktUVsLHjD7ZmB)

{% hint style="warning" %}
If the vibratome is working correctly, the slices should all come away looking the same. If some (e.g. every other slice) is mangled, then something isn't right with the cutting. You may need to cut more slowly or cut thicker.
{% endhint %}

{% hint style="warning" %}
A thickness of as little as 40 microns is usually reliable. If you are seeking to cut slices thinner than 40 microns you will probably need to slice at speeds of under 0.3 mm/s to achieve consistent section thickness.
{% endhint %}


# Step 3: Selecting the imaging area

It's now time to find the surface of the sample, make sure the system is cutting consistently, and decide which area to image.

#### Open the laser shutter

If not done already, open the laser shutter. Hit the "Open Shutter" button. Once opened, the button text will switch to "Close Shutter" and Shutter Open indicator will turn from red to green. Double check [the wavelength is correct](/users/choosing-wavelength).

![](/files/-MAWHVJl6r3JxFTfaSoa)

#### Set the laser power

Set the laser power to a suitable value. Typically about 100 to 150 mW is good, but it will vary based on your labelling and the laser itself (e.g. does it have a pre-chirper?). Higher powers are not necessarily better, as the brighter signal comes from activating fluorophores from a larger volume. In other words, increase in brightness is due to the optical section becoming thicker and hence resolution decreasing.

![The BEAM CONTROLS (laser power) window in ScanImage. Note the power is calibrated here, so we have a value in mW as well as the percent power value.](/files/V6zm3zPRM9jhkmBlsd3p)

#### Finding the sample surface

Prepare the rig for imaging: turn off the lights, shut the enclosure, **then** turn on the PMTs.

{% hint style="warning" %}
The PMTs can be damaged by room or enclosure lights when powered on. Do not turn on the PMTs if the lights are on.
{% endhint %}

Press the green "Preview" button in the main BakingTray window to open the Acquisition GUI, which we will use for navigating the sample.

![](/files/-MCh1mrYOZLKKnPo0icx)

This opens the Acquisition View:

![Acquisition View. The main axes show a schematic of the slide to which the samples are glued. The dark gray rectangle represents the frosted part of the slide. The blue square is the current position of the objective.](/files/V1MdlccsXADGQjgfEZtp)

The stages can be moved by performing a middle-click (mousewheel-click) on the image. Middle-click to where you think the sample should be on the slide (use the representation of the frosted area to guide you). Press "Focus" in ScanImage to start Scanning. You should see the sample. If you do not see anything check the following:

* Is the laser shutter is open?
* Are the PMTs are on?
* Is the laser "Modelock" indicator in the GUI is green?
* Are you definitely over the sample?
* Is the laser power enough?
* Could the image look-up table (right click on image and open the histogram) too stretched out?
* Is the objective Z wrong? If you need to search in Z for the sample, the easiest thing is to place the objective a little too close to the sample and move it away whilst imaging.

The following series of images shows what a brain might look like at a range of depths. Once you have found the brain, focus up and down until you identify the brain surface. In the image series below, this would be somewhere between the -30 and -20 micron depths. The brain surface is very salient: there is a sudden and obvious transition from "nothing" to "brain." Make a note of the surface depth. If you have a motor connected via ScanImage, you can zero the depth reading to mark the surface (see also below).

![A series of depths spaced 10 microns apart. That labeled "0 microns" is suitable depth for the first imaging plane.](/files/-MLT14d-YXKckdUDPdWR)

#### Ensuring slicing is reproducible

The system does not automatically find the brain surface during imaging. Instead, it assumes that the surface of the tissue is a constant distance with respect to the objective for the whole acquisition. This assumption will be correct if the cut thickness is consistent. Now we will check if that is so.

You have already found and noted the depth of the brain surface. Press "Slice once" in the Prepare GUI. This will take a slice: moving the sample up the thickness of one section, slicing the section, then returning the X/Y stage to its original location. If slicing is consistent, the sample surface will be located within 5 or 10 microns of the previous measurement for the last section. If the depth is off by more than about 10 microns, cut again and re-measure. Usually the surface height stabilises within 3 cuts. Sometimes it takes longer and rarely it alternates between thick and thin sections. If this happens, see the [cutting troubleshooting guide](/users/troubleshooting/cutting-problems).

#### Setting the imaging depth

You will likely be imaging multiple optical planes. The first optical plane is that which is visible currently in the ScanImage live preview window. Currently this is the sample surface, which is not evenly illuminated and will probably contain cutting artifacts. We want the first depth(s) to look nicer. Move the objective down about 20 microns. If you have coarse Z control via ScanImage, you can simply enter "20" in the edit box (see below).

![MOTOR CONTROLS window in ScanImage Basic. The objective has been moved down 20 microns with respect to the sample surface at zero microns.](/files/zUu7YfIE9SmygGR7tAUi)

#### Choosing an imaging area

BakingTray acquires either the same rectangular area in all sections (Manual ROI) or automatically finds the tissue to image in each section (Auto-ROI). The following instructions assume you are using the Auto-ROI, as this is suitable for most situations and is faster to run and set up.

{% hint style="warning" %}
The auto-ROI finds and tracks whole samples visible during the interactive preview scans you are about to take. If a sample is not visible at this stage it will not be imaged by the auto-ROI. Either trim down until the sample is visible or use the [manual ROI mode](/users/user_guide/manual_roi_acquisitions). More details on the auto-ROI can be found [here](/users/autoroi_setting_up).
{% endhint %}

Hit the "ROI" button in the Acquisition View and draw a rectangle over the area you wish to do image (see image below). You can drag this box to translate it and pull on an edge to re-size it. If you resize, it will snap to the nearest whole tile. Once you move or re-size the box, its size in tiles is shown at its mid-point. Double-click to accept the ROI.

![The preview window initially presents with just a schematic of the slide (left). Press the "ROI" button and draw a ROI around the area you anticipate the brains to be. Then press return.](/files/HjO9pWUjohtxP7KpsW66)

Press "Preview Scan" (Until [this bug](https://github.com/SainsburyWellcomeCentre/BakingTray/issues/62) is fixed, wait until the scanning starts before changing any GUI values in ScanImage). This will initiate a tile scan of the sample at low resolution using only one optical plane.

An example of a completed preview scan with two brains is shown below. Don't worry about the tile illumination artifacts, those will be cleaned up during final image assembly by [StitchIt](https://github.com/SWC-Advanced-Microscopy/StitchIt).

![Completed preview scan.](/files/wXWlJ8oe1XAPTsYWPK59)

{% hint style="info" %}
After the preview scan is complete, you may zoom back out to see the whole slide by pressing "Slide".
{% endhint %}

### Is the green border clear?

Once you have run a preview scan in auto-ROI mode a green border will appear at the image edge. This region is used for determining the intensity threshold between sample and agar. It is **important** there is no sample in the green zone **and** that the green zone contains agar. If your agar is cropped too close to the sample, alter the look-up table to confirm no out-of-agar pixels exist here. The image below shows a preview scan with brain tissue in the green border. You would re-do this preview scan.

![Auto-ROI preview scan with three samples. The pixels in the green border are used to estimate background. In this case there is sample tissue in the green border so the image needs to be re-taken.](/files/xo2bRkZ6i7RmyZBm30mK)

![The samples have been re-imaged so there is no tissue in the green border. The left brain was mounted so it overhung the slide slightly.](/files/FT5HACL63btTy5QKKmnz)

### The surface of all samples roughly the same?

All samples should look roughly the same and should not have gradients across them in the left/right direction. Such gradients are an indication that the blade is tilted. You can verify this if you suspect it by panning to different brain locations and measuring the brain surface there. See the [Acquisition Problems](/users/troubleshooting/acquisition-problems-and-solutions) section of the troubleshooting guide if the tilt is severe and you can't fix it by just moving the objective down another 10 or 20 microns.

{% hint style="info" %}
Samples of different ages or that have had different degrees of fixation can exhibit very different levels of autofluorescence. This is normal and not a defect in the imaging or cutting.
{% endhint %}


# Step 4: Starting the acquisition

#### Checking the bidirectional phase correction

The software scans bidirectionally for speed. This means that it acquires image data as the fast scan axis moves left to right and also when it returns, moving right to left. Data from odd and even lines will be out of phase if the bidirectional phase correction value is not set properly. An improper values will result in images that appear jagged. Below, the image on the right shows what things *should* look like and the left image shows an example of a bad phase setting.

![Consequence of a bad bidirectional phase correction value. Left shows a bad image and right a good one.](/files/OgNy8C6e8TiA0E2iqf9K)

The phase correction value is set in the CONFIGURATION window of ScanImage:

![ScanImage CONFIGURATION window. The Scan Phase correction slider is highlighted by the orange box.](/files/eXtkuHnDIm4Zob9WuoHb)

To tweak the phase correction value:

* Identify an area of the tissue which has bright features. Ideally thin vertical features that cross many scan lines. You can middle-click on the Preview image to move the stages to that location in the sample.
* Hover the mouse over the live image window of ScanImage and scroll in with the mouse wheel to get a detailed view.
* If only autofluorescence is visible, set the averaging to about 10 frames to get a clearer view. In areas with bright signal averaging is not necessary.
* Ensure that the image is not clipping too much. i.e. if you have the red clipping setting enabled then you shouldn't be seeing much red. Too much clipping will mask out the bidi artifacts.
* Tweak the bidi value by clicking on the slider arrows. Allow a couple of seconds for your changes to have an effect due to the averaging.
* You can also try the "Auto Adjust" button, but be aware that this often fails.
* Return the averaging to the desired value for imaging.

{% hint style="info" %}
If you have galvos only (not a resonant scanner) then line periods shorter than about 800 us will lead to variable phase offsets across the scan line. So either don't use very fast values, or switch to resonant scanning, or apply a correction post-hoc.
{% endhint %}

#### Confirming the beam intensity with z-depth

Deeper optical planes will yield less signal. To compensate for this, ScanImage can increase laser power with depth. We will no confirm that this laser power ramping is reasonable.

Find the BEAM CONTROLS window and if necessary press the "Power Z-Profile" button to expand it. Ensure the exponential option is chosen in the P/Z Adjust drop-down menu. The length constant (Lz) associated with this will determine the rate at which power should increase with depth. A value of about Lz=200 to Lz=500 is normally sufficient.

![Checking power as a function of depth. "Exponential" has been selected with Lz=249. Laser power ramps up with depth over the 8 optical planes shown here. Images look very similar across depth, indicating that the correction is working well.](/files/mUWuB1l7NuKVMyUJ3TQV)

* Place the objective over a region containing mostly grey matter.
* Hit "Grab" in the main ScanImage window. You will now see a grid of images, one from each depth.
* If you have the "High saturated" (bright pixels are red) look-up table, adjust the histogram settings such that only a small number of pixels appear red in the first image (the top plane).
* Adjust Lz. e.g. If deeper images look dimmer, you can increase the slope of the power curve by making the depth constant smaller.

No single value will be perfect throughout the sample. For example, in brains the signal is attenuated *much* faster with depth when imaging white matter compared to grey matter (see below). The attenuation due to white matter can not be corrected by increasing power, so chose areas with mainly grey matter for testing the length constant.

![Areas with a lot of white matter should not be used to assess power/depth](/files/q01HUJGCPTOgRNNFtbjp)

#### Start!

If you are in auto-ROI mode you **must** re-run the preview scan if you have changed laser power or PMT gain since it was originally made. Once you are ready, press "Auto-Thresh" to have BakingTray find the sample. Finding the samples will take about 5 seconds. Once the samples have been found, proposed ROIs are overlaid on top of the image.

![The Auto-Thresh button (highlighted in red) will identify the samples in the FOV. The proposed tile scan is overlaid on top of the brains after a threshold has been found.](/files/g3VPY687l9JQldZZh3FE)

{% hint style="info" %}
More details on the auto-ROI can be found [here](/users/autoroi_setting_up).
{% endhint %}

In both manual and auto-ROI modes you can now hit "Bake" in the Acquisition View to start acquiring the sample

![Press Bake to start the acquisition](/files/-MCkgDpR6-S_IhHgPUZs)

There will be a confirmation dialog box before the acquisition starts and there is a short delay after accepting this before the acquisition begins.

#### After the acquisition has started

You can now start `syncAndCrunch` on the StitchIt analysis machine to begin pre-processing data and sending preview stitched images to the web.

Once the acquisition has started you can pause and resume at any time from the preview window. The following settings can be changed during acquisition:

* Laser power: any time
* Laser power depth ramp: during slicing only
* PMT gain: any time
* Frame averaging: during cutting only
* To alter the number of sections you need to need to stop the acquisition, [resume it](/users/user_guide/acq_resume), then modify the remaining number of sections to image.

Make sure you also read through [Step 5: Concluding the acquisition](/users/user_guide/step_06_concluding-or-restarting-the-acquisition), which sumarises post-acquisition tasks and explains how to resume a stopped acquisition.


# Step 5: Concluding the acquisition

Once the requested number of sections have been acquired, the acquisition will stop automatically and the laser and PMTs will be switched off. If this is an auto-ROI acquisition, it will stop automatically if no tissue found.

## Stopping an acquisition early

Should you wish to stop the acquisition earlier, hit the "Stop" button in the acquire GUI. You will then be presented with a window asking you if you want to halt right now or at the end of the current section. There is also a checkbox indicating if you want the acquisition to be marked as "Finished". If this is checked, a signal is sent to `syncAndCrunch` (a file called `FINISHED` is made in the sample directory) to to start stitching. Note that after manually halting the acquisition, the PMTs are turned off but the laser **remains on**. If you wish to turn off the laser, enter the laser GUI and press "Turn Off".

## Post-acquisition tasks

The following are common tasks you will need to perform on the analysis PC after acquisition is complete.

* You will optionally compress the raw unstitched tiles for long-term storage with the `compressRawData` [command line tool](https://github.com/SWC-Advanced-Microscopy/btpytools).
* Crop excess imaged area if this is a single sample using the `stitchit.sampleSplitter` tool. Cropping is especially important if you performed an auto-ROI acquisition as the algorithm sometimes images an excessively large area in a small number of sections and this **greatly** bloats the stitched image size compared to the unstitched raw tiles.
* If you imaged multiple brains you will use the `stitchit.sampleSplitter` to split these into separate data directories.
* Copy data to a remote server and delete the local copy on the analysis PC with the `transferToServer` [command line tool](https://github.com/SWC-Advanced-Microscopy/btpytools)..

The Python package [btpytools](https://github.com/SWC-Advanced-Microscopy/btpytools) exists for assisting with data compression and transferring data to a remote server.


# Setting up checklist

#### Common steps

* Select Sample -> New from the menu.
* Turn on the laser, open the shutter, and [select the appropriate wavelength for your fluorophores](/users/choosing-wavelength).
* Embed the sample
* Load sample into microscope.
* Set sample directory and sample name.
* Set imaging parameters in main BakingTray window.
* Set channels to acquire in ScanImage CHANNELS window.
* Raise sample and set blade position.
* Take the first slice: ensure blade ends up about 3 mm beyond the edge of the agar.
* Trim off excess agar if needed and approach imaging depth.
* Hit the Auto-Trim button to go from thicker trimming section to the final slice thickness and speed used for imaging.
* Center sample under objective. Open laser shutter. Turn off room lights.
* Find the sample surface, take a slice, then re-measure surface to check for stability.
* Move objective down to imaging depth (e.g. 25 microns below sample surface).

#### autoROI

* Press the ROI button in the preview window and use the slide schematic to draw a box where you expect the samples to be.
* Take a preview scan to ensure that samples don't enter the green border area. This can be at lower power for now. If necessary, increase imaged area. You don't need to re-take the preview scan right now.
* Increase frame averaging to tweak bidirectional scanning. (You can middle-click on the preview image to move the stages to that location in the sample)
* Set laser power and power increase with depth at an area without too much white matter.
* Reset frame averaging and *take another preview* at the final power and PMT settings. Hit AutoThresh.
* BAKE
* After acquisition you should crop the stitched images from even single samples or you will end up with larger datasets than you expect.

#### Non-autoROI

* Find sample ventral midline and use this to set initial imaging area.
* Take a preview scan to ensure that samples are correctly framed. Re-frame as needed.
* Increase frame averaging to tweak bidirectional scanning. (You can middle-click on he preview image to move the stages to that location in the sample).
* Set laser power and power increase with depth at an area without too much white matter. Ensure PMT gains are reasonable.
* BAKE


# Resuming an acquisition

#### Restarting a stopped acquisition

It is possible to resume an acquisition that stopped for whatever reason. The following steps can be performed even if MATLAB crashed or the acquisition was interrupted by a power cut.

Perform the following steps to resume an acquisition:

* Select Sample > Resume Acquisition from the BakingTray menu. Load the recipe file from the acquisition directory containing the sample you wish to resume.
* You will be asked to confirm whether you wish to resume the acquisition.
* Press "Yes" and double-check the parameters in the recipe and prepare GUI.
* You will then be presented with a new GUI asking how the acquisition should be resumed. e.g. if the last section was partially completed, should the existing data be discarded and the section re-imaged.
* You are responsible for turning the PMTs back on. Similarly for ensuring the laser is on and the shutter is open.
* The Acquisition GUI will now appear. Press "Bake" to start the acquisition. *You only need to do another preview scan in exceptional circumstances (see below)*.

{% hint style="warning" %}
Do not re-load the recipe after you have asked to resume. This will revert important settings to default values.
{% endhint %}

#### Notes

* It is not necessary to do another preview scan and repeat the auto-thresh under most circumstances. If you are re-starting the acquisition because of an issue related with the auto-ROI, or because somehow how the sample vanished, etc, then of course you should do another preview and another Auto-Thresh before pressing Bake.
* If you have reason to think the sample surface might have moved (e.g. you have changed the blade) then you might want to take a preview scan first and repeat the auto-thresh. Then watch how it cuts and tweak objective height.


# Manual ROI acquisitions

### Introduction

The manual ROI acquisition mode is a fallback mode for situations where the auto-ROI is not appropriate:

* You wish to image a rectangular sub-region rather than the whole sample.
* The acquisition has to be set up without the sample being visible. e.g. you *have* to have the entire organ and can not afford to trim anything. Note, however, that this situation makes set up more tricky as you can not estimate where the imaging surface lies.
* You have reason to believe the auto-ROI might struggle with your sample (e.g. it has very low SNR or tends to be extensively occluded by membranes).

{% hint style="info" %}
If you consistently encounter minor problem with the auto-ROI, these can generally be corrected by altering how you set up or mount your samples. It is worth figuring out issues with the auto-ROI rather than defaulting to manual mode as a solution. It takes quite a lot of effort to get nice tight ROIs in manual mode and if you are not experienced at this you will either end up clipping tissue or you will create huge ROIs that image a large quantity of empty space.
{% endhint %}

As with the auto-ROI, you will draw a ROI around the area you intend to image and take a preview scan. The challenge with the manual ROI mode is that you have to ensure the ROI is large enough to capture the whole sample, which will likely grow in the X/Y plane as you cut down. You may also have to take into account tilt in sample mounting. You don't want a ROI that is excessively large as this will substantially increase the imaging time.

### Instructions

Using the slide schematic as a guide, press the ROI button to draw a box around the area you expect the sample to lie. You can now drag this box to translate it and pull on an edge to re-size it. If you resize, it will snap to the nearest whole tile. Once you move or re-size the box, its size in tiles is shown at its mid-point. Double-click to accept the ROI.

![](/files/-MCh4BjcVY3MKrnOb7nh)

Reposition and re-draw the ROI if needed.

![](/files/-MCh4Bje1UYU5ZKwybel)

Re-take the preview scan to confirm you selection.

![](/files/-MCh4lTCOGcjrX0I31n4)

When the sample is framed to your satisfaction, you can move on. Remember to take into account the changing size of the sample at later sections and also any tilt in the mounting of the sample that might cause it to appear to translate across the imaged field as cutting progresses.

### Hints for getting tight ROIs

* Know the size of your samples. e.g. mouse brains that are not tilted along the D/V axis will comfortably fit into a ROI that is 9 mm by 11.5 mm. There is no point making your ROI larger, therefore, especially along the lateral direction where tilt is less of a problem.
* Set the laser to visible wavelength and use it as a GUI by scanning or using "point" mode at low power.
* Know your tile size. Use the tiles as a scale bar to assess how much a border your need to add if the sample is tilted. e.g. Mount brains with the ventral surface facing the blade as tilt along the D/V axis is the most problematic. Standing in front of the microscope you can estimate how much the brain will extend beyond what is currently visible in the preview window. Based on the tile size you can the estimate how much to enlarge the ROI and in what direction.
* Use the StitchIt Sample Splitter to crop non-imaged tissue at the end of the acquisition.


# Excitation choices

## Choosing an excitation wavelength

Fluorophores have broader excitation spectra under 2-photon compared to one photon and we image with all channels simultaneously. This means there is more cross-channel bleed-through than other techniques but it also improves imaging times, as quite disparate fluorophores can be imaged with one excitation wavelength. [**Interactive BrainSaw Channel Chooser**](https://SWC-Advanced-Microscopy.github.io/brainsaw_channel_chooser)

![](/files/FbWrLzGPYisMIFnQ4TO5)

![](/files/vzoapOCER4LSDrIuccJe)

## GFP at 800 vs 920 nm

Note that GFP is visible at 800 nm but, as indicated by the table, is much better at 920 nm. The image below is of GAD67-GFP imaged on at 2µm/pixel, 100 mW, on a galvo/galvo microscope. The first (left) image is taken at 800 nm and the second (right) image is taken at 920 nm. Note the auto-fluorescence associated with the vessel is not visible at 920 nm and that signal and contrast for GFP are much better at 920 nm.

![](/files/-MUORCYpIdO1Z6K14wKG)

## Notes

* tdTomato is more efficient at 1040 nm than 920 nm, but the laser emits much less power at 1040 nm. If expression is good, you will find you get the same signal at these two wavelengths, because the fluorophores are saturated. However, if expression is low, you may find you get virtually no signal at 920 nm but acceptable signal at 1040 nm. This could be the case where, for example, tdTomato expression is being driven by cFos.
* For three colours you can use eGFP, eBFP2, and mCherry at 780 nm.
* There is less autofluorescence and less scatter of excitation light at longer wavelengths.
* There is not much background signal in the blue channel at around 900 nm and longer.

### Far red dyes

* Far red dyes are generally worse under 2-p than 1-p excitation; an exception is DiD.
* iRFP 670 looks pretty good at 880 nm in a far-red channel (e.g. 700-661 nm) 1 but it bleaches fairly quickly.
* Alexa 647 bleaches really quickly and produces nasty tiling artefacts as a consequence.
* Alexa-488 and Alexa-647 work well at 780 to 800 nm

## Links

* [Chroma spectra viewer](https://www.chroma.com/spectra-viewer)
* [Fisher - Fluorescent Probes for Two-Photon Microscopy—Note 1.5](https://www.thermofisher.com/uk/en/home/references/molecular-probes-the-handbook/technical-notes-and-product-highlights/fluorescent-probes-for-two-photon-microscopy.html)
* [Excitation Spectra and Brightness Optimization of Two-Photon Excited Probes (Harris, 2012)](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3283774/)
* [Two‐photon excitation and emission spectra of the green fluorescent protein variants ECFP, EGFP and EYFP (2005)](https://onlinelibrary.wiley.com/doi/full/10.1111/j.1365-2818.2005.01437.x)
* [Spectra curves: Zipfel Lab](http://www.drbio.cornell.edu/cross_sections.html)


# Choosing imaging settings

Choosing the correct imaging parameters is important. For example, if you under-sample you risk losing important information but if you oversample you can quickly generate *very* large datasets that are unnecessary for the question at hand. The following information discusses imaging brains.

## Resolution

There are two resolution numbers: X/Y resolution and Z resolution. X/Y resolution is determined by the number of pixels in the image. Z resolution is determined by the spacing between optical planes.\
You should choose these according to what you are trying to *quantify*. Often you will be extracting features with an automated analysis pipeline. The goal is to generate data that are adequate for the pipeline, not data that "look nice". Doing the latter tends to result in over-sampling.

The following table is a general guide. If you are unsure: ask.

| Experiment            | X/Y voxel size   | Z spacing                    |
| --------------------- | ---------------- | ---------------------------- |
| Probe tracks          | 8 to 4 microns   | 20 microns                   |
| Mapping bulk labeling | 8 to 2 microns   | 20 microns                   |
| Cell counting         | 2 to 2.5 microns | 5 to 7 micron optical planes |

The Z resolution numbers above assume you want to register data to the atlas. If you know you don't care about this, then it's totally reasonable to take one physical section every 50 microns and no optical planes.

{% hint style="warning" %}
It is very bad practice to acquire one "pretty" sample at higher quality for use in a figure or presentation whilst the rest of the data are acquired and quantified at lower, but of course adequate, quality. Figures should be representative of the whole dataset. Consider imaging a small number of discarded slices on a confocal if you need to verify that BrainSaw is capturing all relevant detail.
{% endhint %}

For reference, the following image shows a detail in cortex from a transgenic line expressing GFP. It was acquired at 4 microns/pixel. Note that individual cells are clearly visible but the resolution is not quite sufficient for automated counting. The resolution is clearly more than adequate for tracing electrode tracks.

![Detail from a GFP-expressing transgenic line imaged at 4 microns/pixel. Note individual somata are clearly visible.](/files/bjzO6xywLGBg2XGIK8Ff)

### Mapping axonal bulk projections

A common misconception is that mapping bulk projections requires very high resolution to resolve the axons. However, we are not *tracing* single axons here. Instead, we are simply seeking to map to which regions of the brain do the axons go. In other words: which voxels in the 25 or 10 micron Allen Atlas space contain fluorescence? This is why it usually adequate to do this at 4 by 4 by 20 microns. It is *possible* you might need finer resolution in X/Y, but this is unlikely.

{% hint style="info" %}
If you think you need a highly non-isotropic resolution like 2x2x20 microns or 1x1x20 microns, please ask. Often these resolutions are a mistake.
{% endhint %}

### Counting neurons

Currently [cellfinder](https://github.com/brainglobe/cellfinder) requires high resolution in Z as it is designed to find all cells in the brain. In other words, it is not currently designed to cope with the one plane every 50 microns scenario. A suitable resolution for cellfinder is 2x2x5 microns and we have no reason think finer resolution is needed.

### Making atlases

Serial section data is ideal for generating autoflorescent template data that can be to make a new brain atlas. Rules of thumb for these datasets:

1. Acquire z-planes at the maximum resolution at which you intend to make the atlas. e.g. if you will make the atlas at 25 micron and 10 micron, acquire at 10 micron.
2. Do not oversample by more than about 2x in X/Y
3. Use excitation wavelengths of about 800 nm, as autoflouresence is bright here. Acquire one channel only: they will all look very similar.
4. Use about 150 mW at the sample.
5. Average up to 8 frames if you wish.
6. Image as much of the organ as possible.
7. Image samples if different orientations if you see systematic artefacts.

For example, reasonable settings a mouse brain template:

1. 5 x 5 x 10 microns/pixel.
2. 800 nm, 150 mW at the sample, saving only the "red" channel.
3. Average 4 or 8 frames.
4. Embed with a short section of spinal cord so you can set up using that to acquire the whole brain.

## Background channels

Two photon images of fixed tissue contain rich autofluorescence, especially at shorter excitation wavelengths. You must always acquire an autofluorescence background channel to complement your signal channel. This provides contrast so it is possible to tell which features are labelled with your fluorophore of interest vs which are just bright objects in that channel. Background channels are particularly important for sparser signals, fainter signals, or when you wish to run cellfinder. You should overlay the background channel even when visually assessing the data for signal. Faint signals will be more prominent when overlaid on top of an autofluorescence background and there will be no ambiguity regarding whether bright objects are signal or bright background labeling.

![Field of view containing sparse GFP-labelled axons. Left image is a composite that includes a background channel. Right image is the green (GFP) channel alone. Yellow features in the left image are autofluorescence, possibly from lipofuscin. Green features are GFP. These two sets of features can not be unambiguously discriminated using the GFP channel alone (right).](/files/9LIRseDujZnoKh19sItV)

## Averaging to improve image quality

You may choose to average frames to improve image quality. For resonant scanning, this is achieved by altering the Frame Average number in the [ScanImage Image Controls](https://github.com/raacampbell/bakingtray_docs/tree/master/users/user_guide/step_02_setting-up-imaging-parameters.md) window. You may alter this number once the acquisition started but you have to wait until the sample is being sliced to do so. Averaging will not increase the data size but it will slow down the acquisition: a little bit for 4 micron x/y and **a lot** for 2 micron x/y. Think carefully, therefore, if this is worth it. For example, [cellfinder](https://brainglobe.info/documentation/cellfinder/index.html) generally copes well without any averaging. The following image shows sequential physical sections imaged at n=4, n=2, and n=1 frame averaging with an 8 kHz scanner. Pixel size is 2 microns. Neurons are expressing tdTomato. The goal of the experiment is to count somata. The n=4 averaging looks a little smoother but is obviously not needed to count somata. You should **not** enable averaging for datasets such as this: it will hugely slow down the acquisition and provide no improvement for downstream analyses.

![Three sequential sections from a double transgenic mouse (cFos-creERT2 x Ai14) showing averaging of n=4 frames, n=2 frames, and no averaging. Laser is at 920 nm and 150 mW at the sample. The goal of the experiment is count cells with cellfinder. Averaging frames makes the background autofluorescence look smoother but is obviously not going to affect the quality of the cell segmentation. Do not enable averaging for samples such as this.](/files/BBKT0QLmbiaxb3jmIUXt)

You *might* want to average signal if you are trying to resolve faint sparse fibres. Below are two fields of view showing such data. Each panel shows different values of frame averaging. Data acquired with an 8 kHz resonant scanner.

![Two views of faint sparse fibres at different levels of frame averaging](/files/-MLsGlGwvtx3dA9bgbDY)

From this we learn that n=16 provides no advantage over n=8. We see that a lot more fine detail is visible compared to n=1 or n=2. However, **you would need a mechanism of automatically extracting meaning from the higher level of averaging** if it is to be of practical use. Lacking that, you might be better off at n=1 or n=2.

In summary, whether to average and by how much will depend on your question and how you are quantifying features extracted from the images.

## Laser power

Up to a point you can get more signal by increasing laser power. However, beyond a certain point fluorophores can "saturate". Saturation occurs at higher powers when all of the available fluorophores are constantly in the excited state, so further increases in laser power does not produce a corresponding increase in signal. In 2-photon microscopy, going beyond the saturation limit will decrease Z resolution (an effect in some ways analogous to increasing the pinhole aperture in confocal microscopy). Signals can not be quantitatively compared if saturation is taking place, however binary comparisons (signal/no signal) are valid.

The image below shows how faint sparse GFP-labelled fibres are not substantially more visible at 90 mW compared to 175 mW at 920 nm. The main difference between the two images is lower noise in the background autoflourescence. This is either because of increased out of plane fluorescence or because the background fluorescence has a lower quantum yield and so a higher saturation threshold.

![Faint sparse fibres at 920 nm, averaging 4 frames, at 90 mW (left) and 175 mW (right).](/files/wmEarF11RiaIlNgzWT1P)

## Choosing cut thickness

Say you want to image a sample taking planes every 20 microns. That's a little too thin to cut reliably with a steel blade, so you must take thicker sections with multiple optical planes within each section. Cutting thick sections (e.g. 80 microns) with many optical planes will be a little faster but in many tissues the increased scattering from deeper planes will need to a pronounced decrease in resolution and signal strength. As general rule, try to cut as thin as possible to avoid this problem. For PFA-fixed uncleared brains you should be able to cut 40 micron sections at a speed of about 0.35 to 0.5 mm/s.

{% hint style="info" %}
There is no compelling reason to match your z step size to the resolution of the atlas to which you are registering. i.e. there is no harm acquiring data at a higher z resolution then using a lower resolution atlas since the registration will almost certainly end up tilting the brain in the coronal plane. For instance, you might cut 40 micron sections with a 20 micron spacing between optical planes then register to the 25 micron atlas.
{% endhint %}

The following image shows optical planes spaced 10 microns apart. Images show autofluorescence from a mouse brain imaged at 920 nm, starting from the very top of the sample (denoted as -30 microns). Here the field of view is large (about 1.6 mm) and the objective exhibits a good deal of field curvature so it takes 40 microns for the whole FOV to fill with sample. We would start imaging about 35 microns below the surface (about where is shown by 0 microns in this image series). Typically we aim for 40 micron sections, which means we'd acquire the images shown at 0, 10, 20, and 30 microns. The last 5 images look substantially fuzzier: the resolution is worse. For this reason we want to cut thin and start imaging as near to the surface as possible. A smaller FOV or an objective with a flatter field would allow us to start imaging higher up and so the whole stack would look better.

![](/files/-MLT14d-YXKckdUDPdWR)


# Troubleshooting


# Hardware problems

## There is no image

You might sometimes encounter the situation where you have finished trimming, moved the sample in XY under the objective but there is no signal. Now what? The following is a series of checks you can make. Follow them in order. Don't waste time restarting BakingTray and ScanImage as this is almost never going to help.

1. Is the laser shutter open? See indicate on GUI.
2. Is the laser modelocked ("pulsing"). See indicator on GUI.
3. Is the laser power set to a value to typically use? Is the laser wavelength correct?
4. Are the lights in the enclosure turned off?
5. Are the PMTs turned on in ScanImage? Are the PMT gains reasonable?
6. Is the PMT power supply (external controller box) turned on?
7. Did you check the GUI boxes to display at least one channel in ScanImage?
8. Right click on the channel image window and confirm the look up table is set appropriately given the image histogram.
9. If you have a Pockels cell, is it switched on?

If everything above checks out then everything is set up as expected and something else is wrong. Likely either there is no sample visible under the objective, or the laser is not reaching the sample, or the emitted signal is somehow not being detected. Let's deal with these one at a time.

### Check the excitation path

Set the laser to a visible wavelenth, such as 790 nm, and scan at about 150 mW. Turn off the PMT power supply box (leave on the PMTs in ScanImage) and confirm that you see the beam coming out of the objective and scanning over sample. If the beam is over the agar, move the sample in X/Y until it is being scanned try obtaining an image again.

The beam is very bright so even if it looks like it is scanning over the sample, it is possible that most of the beam is being occluded somewhere. If possible, whilst scanning, place a white card in the space between the objective and the lens behind it. You should see a red blurry disk. If it is a weird shape then something is in the excitation path.

{% hint style="danger" %}
If you have been laser safety trained and feel confident, you can follow the beam back along the path with a piece of card and confirm whether something is occluding it.
{% endhint %}

## Laser connection fails

BakingTray controls the laser so that acquisition can be automatically halted if the laser stops pulsing (modelocking). The laser can be controlled via the the "Laser" button in the main GUI.

Sometimes initial connection to the laser fails. If this happens try the following. Firstly, attempt to open the laser shutter because sometimes the laser is in fact connected: `hBT.laser.openShutter` If that fails (it returns `0`) then you will need to try disconnecting and reconnecting to the laser with `hBT.renewLaserConnection`. You can also try this manually:

```
delete(hBT.laser)
hBT.laser = maitai('COM1'); % assuming you have a MaiTai on COM1
hBT.laser.parent = hBT;
```


# Computer problems

## No space left on acquisition PC

BakingTray will no start an acquisition if there is insufficient space on the disk. To solve this we will delete old files. Generally it is OK to delete anything over a month old:

* Empty the Trash.
* Navigate to the data drive in Windows Explorer.
* Select "Details" view and sort by date.
* Select the oldest half dozen or so acquisitions then **hold down shift**, right-click, and select "Delete". With shift pressed, the trash is bypassed and files are deleted right away.


# Cutting problems

If you are having problems with cutting the first thing to do is consider the blade you are using. Particularly if you are using a thinner blade, consider changing to [Campden Instruments stainless steel blades](https://campdeninstruments.com/products/stainless-steel-blades-50), which are verified to work well. These do not rust and are very rigid. Buy in bulk: they are cheaper that way. Expect to use a new blade for each sample but in practice you can image multiple sessions with the same blade if you wish.

Next consider your cutting parameters. In general cutting 40 micron cuts at 0.5 mm/s should work. You might need to cut a little slower in some samples: perhaps down to 0.35 mm/s. Sections much thinner than 40 microns might not sink easily and remain floating on the surface or not will away from the agar.

## Alternate thick and thin (or disintegrating) sections

Vibratomes have a tendency to enter a feedback loop where they cut alternate thick and thin sections. Using the Auto-Trim feature or otherwise slowly stepping down to the final cutting thickness should help reduce the chance of this happening. Sometimes some samples are tricky and this doesn't help. If so, try cutting slower: 0.35 mm/s. If that doesn't help, then take a single section of about 80 microns then go back down to your target thickness. If this also doesn't help, consider imaging with sections 10 to 15 microns thicker.

## Sections coming off as thin strips instead of whole

If all sections are coming off at similar thicknesses but not intact and as a series of ribbons (as show below) then probably the vibratome has something loose.

<figure><img src="/files/KDpIL6hMtKZzOiggACot" alt=""><figcaption><p>These should be complete coronal sections (as are the thick sections towards the top of the image). Instead, all of the thinner sections seen in the middle of the image are cut up into ribbons.</p></figcaption></figure>

The problem shown above is most likely due to a loose blade. When the system is not cutting, gently place your finger on the short side of the blade in the bath and push. Does the blade come away? If so, remove blade holder and tighten blade.

## Slices get stuck to the trailing edge of the agar block <a href="#troubleshooting-slicesgetstucktothetrailingedgeoftheagarblock" id="troubleshooting-slicesgetstucktothetrailingedgeoftheagarblock"></a>

One form of data loss occurs when the slices fail to detach from the agar block and the flap around under the objective. This happens even though the blade proceeds 2 to 3 mm beyond the edge of the agar block (you should always ensure you set the "Cut Size" in BakingTray as a standard part of the set up procedure). The stuck slice obscures the field of view and you lose data. Things that can help alleviate the problem are:

* Try using 5% agar instead of 4%
* Round the corners of the agar (red arrows, below) by slicing them off with a razor blade
* Larger agar blocks (e.g. those that contain 4 brains) seem to exhibit this problem less. Maybe because the weight of the slices is greater and they pull away.

<figure><img src="/files/L5ChtiFOXo3nGjV8qzia" alt=""><figcaption></figcaption></figure>

\\

## Weird black squares visible during acquisition

You may see black tiles or darkened regions of the sample as follows.

<figure><img src="/files/Aa5n6MBnDyWxwvpV7gvt" alt=""><figcaption><p>Image artifacts that originate from membranes sticking out of the sample. These can appear unusual, such as the black square in the upper sample. Note the various darkened areas also.</p></figcaption></figure>

The patches visible above originate from dura or choroid plexus that fails to cut and flap around above the sample. These occlude the sample and cause shadows.

<figure><img src="/files/thFFSDT14X3NpYH2QXTc" alt=""><figcaption><p>Note membranes projecting out of the block face.</p></figcaption></figure>

The membranes can be removed with forceps, but they will likely return as imaging proceeds. The best way of dealing with this is to stop it happening at all. Most samples do not exhibit the problem, only some do and what these have in common is not clear. Things to try include:

* Carefully remove any dura after perfusion but before you post-fix. Only do this if it is obvious what to remove. Avoid damaging the brain.
* Improve your perfusion quality
* Post-fix overnight in 4% PFA at 4 degrees C
* Do not use old PFA.
* Perhaps older animals are worse than younger ones.

Note that larger animals, such as rats and ferrets, will have greater problems associated with shadowing artifacts from membranes.

## There is a dark stripe going down the middle of the sample

The following image shows a darker strip running down the middle.

\\

<figure><img src="/files/wBvLINuy71wzy1wsJMTO" alt=""><figcaption><p>Darker (brownish) stripe up the sample</p></figcaption></figure>

The reason for this darkening is that in this area the brain is thicker. The blade is somehow cutting the sample non-uniformly. Often you can see this by looking carefully at the smaple at a steep angle. It is not clear what causes this. If the effect is not severe, ignore it. If it is severe or you really need to fix it, try changing the blade. If this does not fix it, the problem might be due to the brain not being held tightly in the agar.


# Imaging problems

## Gradient across sample or intensity difference left to right

You see this odd gradient in your images and the gradient is worse in upper optical planes. It may be disappear completely in deeper optical planes.

![Effect of a tilted blade](/files/-MAWiDhDWVFndRoQKmqg)

With multiple brains in particular you might see something as follows.

<figure><img src="/files/MawCa2LeipukoPHGALFp" alt=""><figcaption></figcaption></figure>

Same thing showing the BakingTray preview window and also the on-line preview, which is multi-channel and has tile illumination artifacts corrected.

<figure><img src="/files/3cQ8jKo2uFUVRxqZkS8G" alt=""><figcaption></figcaption></figure>

### **What is happening**

In both cases above, the blade is not parallel to the Y stage. The Y stage is that which moves the sample along the direction parallel to the blade. In the above images, the blade is cutting ventral to dorsal. The blade is deeper on the right of the sample than the left, so when we image there is more tissue above the imaging plane on the *left* half of the image. The image looks a little dimmer on the *right* because the imaging plane is partly out of the brain. This often leads to more tiling artifacts on that side. In the following example, the problem is more severe and is going the other way (blade deeper on the left).

<figure><img src="/files/aiPEArONuPXTO5urgXTY" alt=""><figcaption><p>The blade is tilted such that it is cutting deeper into the block on the left. Note there are also perfusion-related artifacts on the bottom right brain.</p></figcaption></figure>

### How to fix this

Did you forget to push down on the blade holder when tightening it? Loosen the thumb-screw, push down, and tighten it. Cut and check the tilt. If this does not fix the problem, you could try changing the blade. If this also does not fix the problem, you can simply move the objective down a bit. This is a reasonable temporary fix if the tilt is not severe. If the tilt is severe and the samples are important you will need to alter the blade angle. This is a little tricky: if you are not aware how to do it you should get help.

## There is fluorophore cross-talk (bleed-through) between channels

For speed reasons BakingTray acquires all channels simultaneously at a single laser wavelength. Since 2-photon excitation spectra are broad, it is even possible to acquire red, green, and blue fluorophores at single excitation wavelength (780 nm). There will inevitably be some cross-talk between channels since the emission spectra overlap.

![Emission spectra of eBFP, eGFP, and tdTomato](/files/-MOC8-gAJ4H431CwSpuv)

You can not solve this by altering the PMT gains. Decreasing laser power might help: certainly using more power than is necessary is not going to help. You can also try different wavelengths. For example, if GFP is strongly bleeding into tDomato at 920 nm, then try 800 nm. With careful power and wavelength choices, bleedthrough can be minimized. Should this not work, you will need to address the problem at the analysis stage. This could involve simply overlaying multiple channels to identify which fluorophores are present where. Alternatively, you might want to consider some sort of unmixing strategy.

## Optical planes are varying brightness and contrast

Deeper optical planes will naturally be dimmer due to scattering of excitation an emission light. Water immersion objectives aren't corrected for the refractive index of fixed tissue, so imaging deeper will produce more blurry images due to spherical aberration. Issues relating to section thickness are discussed on the [Choosing a resolution](/users/choosing-imaging-settings) page. If, however, you see an obvious increase or decrease in overall signal intensity with depth then you likely did not set up the sample properly.

The image below shows a four brain acquisition with four optical planes spaced 12 microns apart. The brightness increases with depth because the exponential depth constant in ScanImage was set incorrectly. The stripe pattern over the image is electrical noise that is noticeable because this sample was acquired at a low laser power.

![Effect of increasing laser power too much with depth](/files/-MLs5QTaSp9G5t4EWAyL)

For the solution see "Confirming the beam intensity with z-depth" on the [Starting the acquisition](https://github.com/raacampbell/bakingtray_docs/tree/master/users/troubleshooting/broken-reference/README.md) page of the user guide.

### White matter in deeper optical planes always look dimmer

White matter will always look dimmer in deeper depths: there is nothing you can about this other than cut thinner and start nearer the surface. However, you also probably do not need to worry about the images not looking identical in depth. We correct for this in the downsampled image stacks generated by [StitchIt](https://github.com/SWC-Advanced-Microscopy/StitchIt) in case it might influences image registration. This is shown below:

![Orig downsampled stacks](/files/-MLT14d0Y_wtaej6QJb5)

![Corrected downsampled stacks](/files/-MLT14d1Ca5trJaaPN9t)

{% hint style="info" %}
The full-sized stitched images are currently not corrected, but [code exists](https://github.com/SWC-Advanced-Microscopy/StitchIt/blob/master/code/%2Bstitchit/%2BartifactCorrection/correctZilluminationInDirectory.m) to do this if you need it. So far nobody has asked for this.
{% endhint %}

## High frequency laser fluctuations (laser noise)

Multi-photon lasers deliver their light in short, very intense, intense pulses. This is necessary for the two photon effect, which occurs when two long-wavelength photons superimpose in time and space to behave as a single short-wavelength photon. Through this mechanism 920 nm IR light can take the place of blue light to excite GFP. The process of generating the pulses is very sensitive and sometimes lasers will rapidly switch between pulsing and not pulsing or deliver poor pulses. The resulting images show high-frequency stripes and tend to look dimmer than normal. An example of this is reproduced below. If you notice this happening, you can often side-step the problem by changing wavelength by a few nm. Perhaps 5 to 15 nm is needed. These small changes in wavelength tend to have minimal impact on fluorescence signals.\
Sometimes the issue only manifests after the laser has been on for two or three hours. Always report such incidents to the system power user.

![A detail of an image taken in the presence of laser noise. This image is taken on a 4 kHz resonant scanner with 4 frames of averaging.](/files/tfJqwNxiWCs7gK5u8tPN)

![A detail of a normal image from the same sample showing no laser noise.](/files/hzuhps4gLgyCeATB9hSZ)


# Data structure

A single sample directory contains one sample (one imaging session). Within this you will find the following files:

This directory contains:

* *recipe\_XXX.yml* -- This text file is [YAML formatted](https://en.wikipedia.org/wiki/YAML) and contains the parameters the user entered to set up the acquisition. It also contains extra information generated by BakingTray, such as the scanning parameters. This file is required for the individual images to be assembled (stitched) into full planes.
* *acqLog\_XXX.txt* -- Logs major acquisition events, the laser state, and the time take for each section. This file is mainly for record keeping and is not required to stitch the images. It may be used by BakingTray for certain operations, such as resumption of a finished acquisition.
* The *rawData* directory is created when acquisition starts. Within it are a series of section directories. Each section directory contains data from one physical section. e.g. if the sample name is `AMo_20` you will see:

  ```
  $ ls -l rawData
  ls -l rawData/
  total 0
  drwxrwx--- 1 user users 5526 Aug 11 10:29 AMo_20-0001
  drwxrwx--- 1 user users 5526 Aug 11 10:31 AMo_20-0002
  drwxrwx--- 1 user users 5526 Aug 11 10:32 AMo_20-0003
  ...
  ```
* Within each *section directory* you will find the image files. If you are using ScanImage for the acquisition and doing tile-scanning (grid of images) then each TIFF will contain all depths from all channels for each x/y position. So if you have a 3 x 3 tile grid, there will be 9 TIFFs per section directory. Once all tiles have been acquired, an empty file called `COMPLETED` is added. There is also a file called `tilePositions.mat`, which contains the position of each tile in the grid (including the stage coordinates reported by the stage). This file is created by the callback function `SIBT.tileAcqDone` which in a tile scan runs at the conclusion of each X/Y position.

## Developer information

* The recipe file is generated by `recipe.writeFullRecipeForAcquisition` (the API command is `hBT.recipe.writeFullRecipeForAcquisition`).
* The \_acqLog\_XXX.txt file is created during acquisition by `BT.bake`.


# autoROI

### What is autoROI?

With conventional acquisitions the user draws a box around the area they wish to image and the resulting set of x/y positions is applied to all sections. The main drawback of this approach is that for most samples much of the imaged area will be blank. Inexperienced users might draw boxes that cause them to lose data or draw vastly larger boxes than necessary. It takes time to learn how to draw a box that tightly captures the tissue of interest across all slices. To solve this problem, the `prerelease` branch of BakingTray now has an "autoROI" feature. The following video shows it in action on a simulated sample.

{% embed url="<https://www.youtube.com/watch?v=yHEkR3nZsOw>" %}

### How does it work?

The user takes a preview image as before: imaging the entire sample (or samples) with a low resolution tile scan. The software uses this image to calculate a threshold separating tissue from non-tissue. To do this, the software uses pixels along the borders of the preview image, which it assumes will contain no sample tissue. The minimum bounding-box around the sample is calculated, expanded a little for caution, and fitted with a tile pattern. After the user presses "Bake", this tile pattern is imaged. Once each section is complete the location of the sample is calculated again and fitted with a new tile pattern.

Brains like, most samples, tend to present a small surface area initially, before becoming larger and then smaller again. The auto-ROI handles this gradual increase in exposed area by adding a generous border around the area being imaged.

The autoROI will image about 20% fewer tiles compared to a perfectly-drawn ROI. In practice the autoROI reduces imaged tiles by as much as 50% for users who are overly generous with their manually drawn ROIs.

### Constraints

* All samples must be visible in the first preview image. If you have multiple samples that are different heights simply make sure they are mounted such that they all appear at the same time. ROIs associated with shorter samples that end early will just disappear.
* ROIs are rectangular bounding-boxes meaning that still some blank tiles will persist.
* Your preview image should not contain sample tissue at the edges. Ideally it also should be small enough that the edges of the preview still contain agar. i.e. don't image a ridiculously large preview area.
* It is known to work poorly for samples which contain one more fairly isolated regions each of which present a small surface area (e.g. two or three tiles) and may become occluded by flapping membranes.
* You must crop samples (even single samples) after acquisition or your final data size will be larger than before. This is because the ROIs can be larger than person would have drawn for some sections.

### Embedding samples

The agar autofluoresces slightly. You should avoid the possibility that the field of view will contain regions without agar, as the algorithm may then consider the agar to be the sample and enlarge the imaged area substantially. This is best avoided by mounting brains with a substantial agar border:

![A brain well-mounted for use with autoROI](/files/-MLwB8xNeg_hOKUsqNKn)

Here is an example of how the autoROI failed to produce any benefit with three brains embedded in small agar blocks. The image shows a stitched plane from one physical section. The look-up table is adjusted to show to the weak signal from the agar. Note how the algorithm has identified the agar as tissue and is imaging that. The final imaged area will be very large and the acquisition will run more slowly than a well-drawn manual ROI.

![Three brains poorly mounted for autoROI acquisition](/files/-MLyVrfvsLYgGRZheC5Z)

### How to use it

The following instructions should be carried out after you have set the objective height and sorted out the bidirectional phase correction: [see the checklist](/users/user_guide/checklist). Set the acquisition mode to "Tiled: auto-ROI" in the main window.

![](/files/-MCwa4uHoFQv76MtsHk_)

Before taking the preview, make sure you have set the PMT gains and laser power to the values you plan to use during imaging. You can change them a bit later, but it's best if you are at or close to the final values right now. Open the Acquisition Preview GUI and run a Preview. In auto-ROI mode, BakingTray will automatically take the preview with all channels that you will later go on to save. You do not need to check/uncheck the channels to display yourself. Your finished preview will have a green border zone around the edge. It is **important** that:

* There is no sample in this area
* It contains agar

Re-take the preview if there is sample in this border region. You *do not* need to leave a really big gap between the sample and the edge: the sample just has to not enter the green zone. The agar auto-fluoresces and you will skew the threshold obtained by the auto-ROI if the green zone is outside of the agar. Change the look-up table to confirm the green border contains agar. Once you have a suitable preview image, press the "Auto-Thresh" button.

BakingTray will calculate the threshold between tissue and non-tissue pixels, identify where the sample or samples are located, and overlay the resulting tile pattern:

![](/files/-MCwa4uO7DTGu_Jhzv8s)

You will notice that the BakingTray has automatically selected a channel for the preview. This will be the channel with the brightest overall signal. You can not change this. Once you are done press "Bake".

### Post-acquisition: stitching, cropping, etc

On the web-preview you should see that the sample always largely fills the image area, which changes size as the acquisition progresses. The final stitched images will all be of the same size. They are padded with zeros so the sample is continuous across sections.

If you use the sample splitter tool you may find the "auto" feature fails because it is confused by the zero padding. You will probably have to draw ROIs manually.

If you have acquired only one sample at high resolution it is still good practice to crop it to reduce data size. This is because the autoROI is slightly generous with the imaged area to avoid losing tissue. In some cases it might add an extra row of tiles which then get propagated to all sections when the sample is stitched.

### How well does it work?

In case you are wondering how well it works (will you lose data?) then read on: The feature was developed using real BakingTray preview image stacks from 133 past acquisitions encompassing over 300 samples. The acquisitions included a variety of organs, multiple samples and single samples per acquisition, and plenty of problematic recordings (low SNR, occluded tissue, mounting problems, etc). The algorithm parameters were tweaked using this large and diverse dataset and, despite the challenge, performed near perfectly. There is never major data loss: at worst there is negligible tissue loss around the sample edges. In 88% of samples less than 1 tiles worth of tissue was missed. In 95% of cases less than 5 tiles worth of tissue was missed.

![Number of missed tiles across all test datasets](/files/-MDQW6g1BXOgOik7RWAn)

Acquisitions with the most tissue loss were almost all unusual cases which exhibited problems such as very low signal to noise or were otherwise badly set up. The algorithm is robust to floating sections obscuring the tissue and will abort the acquisition if no sample tissue at all is found. Acquisitions with multiple samples are easily handled; ROIs will merge if samples become closer together and un-merge again later as needed.

The worst performing example where the samples are of high quality is this (red boxes indicate imaged areas):

![](/files/-MFBSW1y9y2LMld4AqD6)

The autoROI has been used to run hundreds of real acquisitions and has so far performed well.


# Developers


# 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.


# Developer notes

This page is currently in note-form and contains a variety of useful information. This content will eventually be categorized more carefully.

## Modifying properties of the BT object using a startup file

The best way to change properties in `hBT` is not by modifying the class file but using a startup script. To do this, make a file called `startup_bt.m` in the `SETTINGS` directory and in there any changes. e.g.

```
hBT.someProperty=123
```

This will be run each time BakingTray starts.

## Simulated mode

You may run BakingTray on any machine with no acquisition hardware or even now ScanImage install by running: `BakingTray('dummyMode',true)` Most features should work but simulated mode is less well tested than normal operation. Simulated mode assists in development whilst not at the rig.

## Running a minimal acquisition and benchmarking

You can initiate a minimal acquisition with no tile saving and even no GUI by setting up the recipe and then running:

```
>> hBT.runTileScan; hBT.scanner.armScanner; hBT.scanner.initiateTileScan
```

If you have the GUIs open then any relevant listeners in those GUIs will still fire. This is useful for working out things like timing bottlenecks. For example see [issue #23](https://github.com/SWC-Advanced-Microscopy/BakingTray/issues/23). It's probably a good idea to benchmark a short acquisition if you're made changes to the acquisition GUI or to the `SIBT` tile acquired callback.

## To run the stages through a tile scan via the API

```
>> hBT.scanner.armScanner; 
>> hBT.runTileScan;
```

* Running in dummy mode on an office PC:

  ```
  >> %If no BakingTray in the path, cd to the project path and run:
  >> addBTtopath
  >> BakingTray('dummyMode',true)
  ```

## Caching dynamic values

Things like the `NumTiles` and `TileStepSize` properties of the recipe are calculated on the fly. So don't access these repeatedly in a time-critical loop.

## Running BakingTray with a dummy laser for testing

Although it's possible to start BakingTray in "dummyMode" (see `help BakingTray`) for running without any hardware, you might want to run with just one hardware component missing. Running with a simulated laser attached is useful, since it allows the acquisition to proceed with the physical laser switched off. Start BakingTray normally then do the following:

```
>> hBT.laser=dummyLaser;
>> hBT.laser.parent=hBT;
```

## How BakingTray access data from ScanImage to build the preview

The callback function `SIBT/tileAcqDone` is run by ScanImage each time a tile position has been acquired. This happens because the `SIBT` constructor adds a listener to the ScanImage object at `hSI.hUserFunctions.acqDone`, one of the hooks for the ScanImage User-Functions. The `tileAcqDone` callback captures the last acquired images, downsamples them, and places them in `hBT.downSampledTileBuffer`, where other methods easily have access to the data.

## How is the tile pattern generated?

The acquisition settings are stored in `BT.recipe`. The tile pattern is produced by the method `BT.recipe.tilePattern`, which generates an n-by-2 matrix. Each row is a different tile position. The first column is the X stage location and the second column the Y stage location. The matrix is generated by `generateTileGrid`, which is a function local to `BT.recipe.tilePattern`. This function produces the tile pattern based upon the following variables:

* The microscope FOV: extracted from the scanner.
* The amount of overlap needed at adjacent tiles: set by the user.
* The size of the sample along X and Y: set by the user.
* The "front/left" position of the whole pattern (this is just an offset): supplied by the user and stored in the structure `recipe.FrontLeft`

The size of the sample in mm along X and Y is converted into tiles using the class `NumTiles`, which is attached to `recipe`. The `NumTiles` class returns the number of tiles needed to cover the desired area in X and Y. It does this based upon the length and breadth of the bounding box and the tile overlap. At the command line you can do:

```
>> hBT.recipe.NumTiles.X      
ans =
    11

>> hBT.recipe.NumTiles.Y
ans =
    12
```


# Motion control classes

The system uses five linear motion devices:

* x and y stages for tile scanning and cutting.
* a linear actuator for vertical motion of the x and y stages before cutting.
* a PIFOC for rapid imaging of multiple optical sections in one physical section.
* an optional coarse objective z-stage for positioning the imaging plane at the cutting plane. This isn't controlled by BakingTray.

The design principle of BakingTray is that each hardware item is associated with an abstract class. Hardware are grouped in reasonable ways using classes. e.g.

* Each physical device that provides linear motion is represented by an abstract `linearstage` class.
* Each physical control device for each actuator or stage is represented by an abstract `linearcontroller`. One more `linearstages` can be attached to each `linearcontroller`.
* The BT class brings together the above and also controls ScanImage.

You must set up your concrete classes so that the following conventions are maintained: a) The linear actuator that handles the stage jack (which pushes the sample up and down) is at zero when fully lowered. Upwards locations correspond to posititive numbers. b) The X and Y stages are zero when at the mid-point of their travel ranges. c) -x is left and +x is right. d) -y is towards you and +y is away from you.

An abstract `linearstage` class declares the methods and properties used to control an abstract linear motion device. The `linearstage` class can not be instantiated. Methods are defined in concrete classes (which can be instantiated) that inherit `linearstage`. Whilst it is not necessary for MATLAB classes to be designed this way, the linearstage class serves as a useful starting point for users wishing to write new concrete classes to control custom hardware. To aid this, `linearstage`contains extensive comments describing the assumed behavior of each abstract method it declares.

The `linearstage` is mainly in charge of defining the physical properties of the motion. e.g.

* The ID of the stage
* Stores the current position
* The position units
* The acceleration
* Target speed
* Range of motion (hard and soft limits)

The linearcontroller creates a consistent interface between the controller API (e.g. the manufacturer-specific motion commands) and Baking Tray. Thus the linearcontroller has methods that do the following sorts of things:

* absoluteMove
* stopAxis
* setMaxVelocity
* etc, etc

Of course the `linearcontroller` must perform these actions *on* some physical device. It performs these actions on one or more `linearstage` stage objects with which it is associated. The `linearcontroller` contains an `attachedStage` property. To this we attach one stage object. Say a single physical controller handles both the X an Y stages. We would attach it twice: `BT.xAxis` and `BT.yAxis`. Each will have a different stage. The author of the `linearcontroller` for this stage type is responsible for having the controller read which stage it's attached to and send the correct command out.

## How motion control classes are "assembled" when BakingTray starts

When you run `BakingTray` MATLAB creates an instance of the object `BT`. This is what the line `hBT = BT(BTargs{:});` does in the the `BakingTray.m` file. In the constructor of `BT` you will see `obj.componentSettings=BakingTray.settings.readComponentSettings;` where we extract the settings for the hardware. This are read from the `componentSettings.m` file in the `SETTINGS` directory (For more information on this file [see here](https://github.com/raacampbell/bakingtray_docs/tree/0c8d927e510fd6ee01f5b6cf198c69cd55632924/getting-started/finishing_the_installation/The-Settings-Files.md). A little further down in the constructor you will see that the method `attachMotionAxes` is used to build control classes based on the provided settings. This is done via the `buidlMotionComponent` function in `code\components\motion`.

## Annotated example: connecting to a PI C-891 at the command line

This example shows how to connect to a PI C-891 motion controller and associated stage at the command line without reference to other aspects of BakingTray described above. This is essentially what is done in the `build_C891_stages` sub-function in `buildMotionComponent`.

```
>> STAGE = genericPIstage;
>> STAGE.axisName='someName'; %Does not matter for this toy example
>> PIC891 = C891(STAGE); %Create  control class
>> controllerID.interface='usb'; %We will connect via USB...
>> controllerID.ID= '116010269'; %Using the serial number of the C891
```

Now we are ready to communicate with the device and connect to it:

```
>> PIC891.connect(controllerID)
Loading PI_MATLAB_Driver_GCS2 ...
PI_MATLAB_Driver_GCS2 loaded successfully.
Attempting to connect to C-891 with serial number 116010269
```

If you saw no errors, you can now do stuff like move the stage:

```
>> PIC891.absoluteMove(0)

ans =

     1
```


# The recipe file

BakingTray uses so-called "recipe" YML files to determine the settings with which an acquisition is conducted. A recipe contain settings that are deemed more or less likely to change between samples:

* `sample.ID` - A string defining the name of this sample. This is used to create directory names and so can not include problematic characters. If these are entered they are automatically substituted with something better.
* `sample.objectiveName` - The name of the objective. This can be any string and is not used for anything.
* `mosaic.sectionStartNum` - Number defining the index of the first section. Generally, this should be left at `1`
* `mosaic.numSections` - Integer defining how many sections to take
* `mosaic.cuttingSpeed` - How fast to cut the block in mm/s
* `mosaic.cutSize` - How long the cut should be in mm
* `mosaic.sliceThickness` - How thick the cut slice should be in mm
* `mosaic.numOpticalPlanes` - Integer defining into how many optical planes the slice should be divided. e.g. if the slice thickness is 0.1 (100 microns) and the number of optical planes is 10 then BakingTray will image 10 sections spaced 10 microns apart.
* `mosaic.overlapProportion` - The proportional overlap between adjacent tiles in x/y. A value of "0.05" means 5% overlap. We don't use the overlap to guide tile placement, so this number doesn't have to be large.
* `mosaic.sampleSize.[XY]` - The size of the sample in mm along X and Y.
* `mosaic.scanmode` - Currently this should be the string `tile`. If other scan modes are added later, such as stage-scannng, or auto-finding the sample then this will be changed.

Generally you will edit the recipe via the GUI.


# Auto-ROI

Details for developers and power-users

## Introduction

This feature is currently available in the `prerelease` branch. A high-level overview and user instructions can be found [here](/users/autoroi_setting_up). The feature was originally developed in a [standalone repository](https://github.com/SainsburyWellcomeCentre/autofinder) but has [since been merged into BakingTray](https://github.com/SainsburyWellcomeCentre/BakingTray/commit/c528634a9e99f44239e0de1a356006fea232c9b5).

Getting this feature right is very important: if it makes mistakes there could be data loss. Accordingly, a library of 133 past acquisitions (many with multiple samples so in total there are over 300 samples) was used to test the algorithm. Almost all samples used were rat or mouse brains. Development of this project was highly test-oriented: changes to the code were always checked against a reference result set.

## Generating pStack files

A `pStack` is a structure containing a preview image stack along with some extra information. These were used for developing the auto-ROI feature. For example, the command `autoROI.test.runOnStackStruct(pStack)` calculates bounding boxes for a whole acquisition. We can then evaluate if a good job was done and tweak the algorithm accordingly.

The input argument `pStack` is a structure which needs to be generated by the user. It's a good idea to generate these and store to disk in some reasonable way. e.g. Inside sub-directories divided up however makes sense, such as one directory containing all acquisitions of single samples, one with two samples, etc. To generate a `pStack` file do the following

We will work with imaging stacks (`imStack`, below) obtained from the BakingTray preview stacks.

```
>> nSamples=2;
>> pStack = autoROI.groundTruth.stackToGroundTruth(imStack,'/pathTo/recipeFile',nSamples)

pStack = 

  struct with fields:

               imStack: [1138x2826x192 int16]
                recipe: [1x1 struct]
    voxelSizeInMicrons: 8.1855
     tileSizeInMicrons: 1.0281e+03
              nSamples: 2
             binarized: []
               borders: {}
```

There are two empty fields (`binarized` and `borders`) in the `pStack` structure. These need to be populated with what we will treat as a proxy for ground truth: which regions actually contain brain. This is necessary for subsequent evaluation steps but is not necessary to run the automatic tissue-finding code. This is done with:

```
pStack=autoROI.groundTruth.genGroundTruthBorders(pStack,7)
```

And the results visualised with:

```
>> volView(pStack.imStack,[1,200],pStack.borders)
```

Correct any issues you see by any means necessary.

## Generating bounding boxes from a stack structure

```
>> OUT=autoROI.test.runOnStackStruct(pStack)
```

Visualise it:

```
>> b={{OUT.roiStats.BoundingBoxes},{},{}}
>> volView(pStack.imStack,[1,200],b)
```

## Evaluating results

Here we run the algorithm on all `pStack` files. First ensure you have run analyses on all samples. Run the test script on one directory:

```
>> autoROI.test.runOnAllInDir('stacks/singleBrains')
```

You can optionally generate a text file that sumarises the results:

```
>> autoROI.test.evaluateDir('tests/191211_1545')
```

To plot all samples:

```
autoROI.evaluate.plotResults('tests/191211_1545')
```

To visualise the outcome of one sample:

```
>> load LIC_003_previewStack.mat 
>> load tests/191211_1545/log_LIC_003_previewStack.mat
>> b={{testLog.BoundingBoxes},{},{}};
>> volView(pStack.imStack,[1,200],b);
```

To run on all directories containing sample data within the stacks sub-directory do:

```
>> autoROI.test.runOnAllInDir
```

## Running re-runnin autoROI on particular section from a test acquisition

```
pStack.imStack(:,:,30:end)=[]; % We only care about the first few sections
OUT_S=autoROI.test.runOnStackStruct(pStack); % run on all

% We notice a problem around section 23, so let's run just that 

tmp_s=OUT_S;
tmp=pStack;
ind=23;
tmp.imStack = pStack.imStack(:,:,ind);
tmp_s.roiStats(ind:end)=[];
autoROI(tmp,'lastSectionStats',tmp_s,'showbinaryimages',true); % Shows outcome for this section only
```

### How the auto-ROI works

The general idea is that bounding boxes around sample(s) are found in the current section (`n`), expanded by about 200 microns, then applied to section `n+1`. When section `n+1` is imaged, the bounding boxes are re-calculated as before. This approach takes into account the fact that the imaged area of most samples changes during the acquisition. Because the acquisition is tiled and we round up to the nearest tile, we usually end up with a border of more than 200 microns. In practice, this avoids clipping the sample in cases where it gets larger quickly as we section through it. There is likely no need to search for cases where sample edges are clipped in order to add tiles. We image rectangular bounding boxes rather than oddly shaped tile patterns because in most cases our tile size is large.

#### Implementation

`imStack` is a downsampled stack that originates from the preview images of a BakingTray serial section 2p acquisition. To calculate the bounding boxes for section 11 we would run:

```
autoROI(imStack(:,:,10))
```

The function will return an image of section 10 with the bounding boxes drawn around it. It uses default values for a bunch of important parameters, such as pixel size. Of course in reality these bounding boxes will need to be evaluated with respect to section 11. To perform this exploration we can run the algorithm on the whole stack. To achieve this we load a "pStack" structure, as produced by `autoROI.test.runOnStackStruct`, above. Then, as described above, we can run:

```
 autoROI.test.runOnStackStruct(pStack)
```

How does `autoROI` actually give us back the bounding boxes when run the first time (i.e. not in a loop over a stack)? It does the following:

* Downsample the stack again to a fixed size: currently 50 microns.
* Median filter the stack with a 2D filter
* On the first section, derives a threshold between brain and no-brain by using the median plus a few SDs of the border pixels.

  We can do this because the border pixels will definitely contain no brain the first time around.
* On the first section we now binarize the image using the above threshold and do some morphological filtering to tidy it up and to expand the border by 200 microns. This is done by the internal function `binarizeImage`.
* This binarized image is now fed to the internal function `getBoundingBoxes`, which calls `regionProps` to return a bounding box.

  It also: removes very small boxes, provides a hackish fix for the missing corner tile, then sorts the bounding boxes in order of ascending size.
* Next we use the external function `autoROI.mergeOverlapping` to merge bounding boxes in cases where the is is appropriate. This function is currently problematic as it exhibits some odd behaviours that can cause very large overlaps between bounding boxes.
* Finally, bounding boxes are expanded to the nearest whole tile and the merging is re-done.

### Making summaries

`autoROI.test.evaluateBoundingBoxes` works on a stats structure saved by `autoROI.test.runOnAllInDir`. We can do the whole test directory with `autoROI.test.evaluateDir`.

### Unit tests

Testing revolves around ensuring that the output of the algorithm is unchanged (or improved) following modifications to the code. e.g. This can be used to check whether the current commit produces a result directory at least as good as the last good reference run. To test for this:

```
>> cd ./previewStacks
>> autoROI.test.runOnAllInDir('stacks')
```

This produces an output in `previewStacks/tests`. If this is the first time you are doing this and need a reference then output of the test should be moved to `previewStacks/test_reference`. So you have:

```
previewStacks/stacks
previewStacks/test_reference
previewStacks/tests
```

To look at the results, `cd` to the `tests` directory and run `autoROI.evaluate.plotResults(PATH_TO_previewStacks)`. e.g.

```
>> autoROI.evaluate.plotResults('/Volumes/data/previewStacks/tests/210413_1441')
```

To compare to the reference stack:

```
autoROI.evaluate.compareResults('./test_reference','/Volumes/data/previewStacks/tests/210413_1441')
```

#### Example usage within BakingTray

Load a preview stack, "take" a preview image, find the threshold, calculate and display the bounding boxes.

```
hBT.scanner.attachPreviewStack(pStack);
% press "Preview Scan" in the GUI
hBT.getThreshold
```

In the API we find:

```
>> hBT.autoROI

ans = 

  struct with fields:

    previewImages: [1x1 struct]
            stats: [1x1 struct]

>> hBT.autoROI.previewImages

ans = 

  struct with fields:

               imStack: [962x570 double]
                recipe: [1x1 recipe]
    voxelSizeInMicrons: 20
     tileSizeInMicrons: 966.6333
              nSamples: []
               fullFOV: 1

>> hBT.autoROI.stats

ans = 

  struct with fields:

        origPixelSize: 20
    rescaledPixelSize: 50
             nSamples: []
             settings: [1x1 struct]
             roiStats: [1x1 struct]

>>
```

You can now overlay the bounding boxes with `hBTview.view_acquire.overlayLastBoundingBoxes`. You can even overlay the tile pattern:

```
z=hBT.recipe.tilePattern(false,false,hBT.autoROI.stats.roiStats.BoundingBoxDetails);
hBTview.view_acquire.overlayTileGridOnImage(z)
```


# Simulated mode

BakingTray has a simulated or "dummy" mode which allows it to run on any OS with no hardware connected. Not all features are supported. The simulated mode was initially used only to assist in basic GUI development. More recently (April 2020 on `dev`) it was extended to allow preview and baking by loading correctly formatted and downsampled past data. There are some restrictions still: it's only been tested with one optical plane and channel. Nonetheless, quite a lot is possible and simulated mode can easily be extended to encompass more features.

## Starting

```
BakingTray('dummyMode',true) % Start simulated mode

% Load and attach a preview stack:
load('/Path/To/Stack/CA_123_ApreviewStack.mat')
hBT.scanner.attachPreviewStack(pStack) % Attach it to the scanner
```

For details on the preview stack format see: <https://github.com/raacampbell/autofinder> Everything below is tested with stacks downsampled to 20 µm per pixel.

## Interacting with the dummy scanner

The main window has a "Scanner" menu. Go there and select "Open dummy scanner": a new window opens. Here you can select "Scanner > Acquire Tile" to see the current physical section (top) and the current tile (bottom). The position of the virtual stage in the stack is indicated by the red cross.

You can open the Prepare GUI (at the command line: `hBTview.startPrepareGUI`), edit the stage position and acquire a new tile. You can select "Scanner > Start Focus" to pan around the sample with the on-screen arrows or WASD whilst seeing the current tile update. When you are finished you can "Scanner > Stop Focus".

## Preview and Bake

Use the GUI to set a path to save the data to or at the command line do: `hBT.sampleSavePath='~/Desktop/TEMP';` or similar. Open the prepare GUI (at the command line": `hBTview.startPreviewSampleGUI`). Press "Preview Scan" and you will see the the image appear tile-wise whilst the dummyScanner window updates. For more advanced testing, you might want the GUI to update faster. In this case you can disable updates of the dummyScanner window: `hBT.disabledAxisReadyCheckDuringAcq=true;` You can also control how many tiles must be acquired before the preview window updates. For example compare `hBTview.view_acquire.updatePreviewEveryNTiles=2;` to `hBTview.view_acquire.updatePreviewEveryNTiles=20;`

Bake also works. You can slightly speed up longer acquisitions by setting the following:

```
hBT.disabledAxisReadyCheckDuringAcq=true; % Skips some methods we don't care about

% Reduce the number of screen updates for speed reasons
hBT.scanner.displayAcquiredImages=false;
hBTview.view_acquire.updatePreviewEveryNTiles=50;

%Reduce the number of log messages
hBT.logMessageThreshScreen=6;
hBT.logMessageThreshFile=6;
hBT.yAxis.logMessageThreshScreen=7;
hBT.yAxis.logMessageThreshFile=7;
hBT.xAxis.logMessageThreshScreen=7;
hBT.xAxis.logMessageThreshFile=7;
hBT.zAxis.logMessageThreshScreen=7;  
hBT.zAxis.logMessageThreshFile=7;
```

## Stitching simulated data

The easiest way is to name you simulated rig something like "TEST" then make a `stitchitConf_TEST.ini` file. In that file under `[tile]` set:

```
doDrop=0
tileRotate=2
tileFlipLR=0
```

You should now get acceptable stitching.


# Contributing

Contributions to *BakingTray* are welcome.

* You should [fork the repository and send contributions as a pull request](http://thepilcrow.net/explaining-basic-concepts-git-and-github/) and keep your fork up to date [or it will become difficult to merge your changes](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request).
* New functions you add should have detailed help text like that in [stitchSection.m](https://github.com/SainsburyWellcomeCentre/StitchIt/blob/master/code/stitching/stitchSection.m)
* If you modify the arguments in an existing function you should also update the function's help text.
* Many small commits are better than single big ones.
* Keep your pull requests clean. e.g. do not include commented-out test code, temporary functions, or highly specialised functions such as `BakingTray_forMyRigOnTuesdays.m`.
* Do not add your own INI files, recipe files, or other settings files. The `SETTINGS` and `SETTINGS_BACKUP` directories must be empty but for the `.gitignore` file.
* Use spaces instead of tabs for indenting.

## Branches

Development is distributed across three branches:

* `master` - Finalised code ready to be shared with others. Must be stable. Merge into here from `prerelease`.
* `prerelease` - Tested code that can be run on a live system but may have bugs. Merge into here from `dev`.
* `dev` - All development goes here. Unstable.

You should keep the number of commits low on `master` and `prerelease`. The development cycle goes as follows.

* Check out `dev` and ensure it's up to date with `master` and `prerelease`.
* Make changes and commit to `dev`.
* Perform basic tests. e.g. ensure no obvious bugs are present. Run any unit tests, should they be available, or write unit tests.
* List changes in the changelog. Assume the changelog will be read by users.
* Merge to `prerelease` **with a merge-commit** to keep things neat.
* Run the system on `prerelease` for a time to ensure no regressions are present.
* Merge `prerelease` into `master` **with a merge-commit** to keep things neat in the master branch.


# FAQ

## Motion control

### How do I see the status of the the axes?

Run `hBT.getStageStatus` to get a report on how each axis is set up and other important information.

### My PI direct-drive stages are cutting out and/or giving over-current errors

If necessary, set the D terms of the PID loops to zero then at the MikroMove command line run the phase finding command: `FPH 1`. The axis has to be enabled (i.e. `EAX? 1` returns `1`) and the servo mode has to be off (`SVO? 1` returns `0`). You can query the result of the phase-finding operation with `FPH?`. This should return a positive value. `-1` indicates that the phase finding operation failed. If it worked, the new value can be saved to non-volatile memory via the command `WPA 100`

Once this is done, enable the servo and see if performance improves. If not you could try setting a small positive D term to the position PID loop (e.g. 0.005) but be cautious of going too far as this may increase position noise.

If you have simply knocked the stages and caused the servo to cut out, you can test for this by running the BakingTray command `hBT.getStageStatus`. If, say, the X axis is listed as disabled you can try enabling it with `hBT.xAxis.resetAxis`.

## Scanning

### Is BakingTray scanning software?

No it's not. BakingTray uses external scanning or image acquisition software to obtain images. Currently only [ScanImage](http://vidriotechnologies.com) is supported. BakingTray interacts with ScanImage indirectly via the [SIBT class](https://github.com/SainsburyWellcomeCentre/BakingTray/tree/master/code/components/scanning/%40SIBT).

### Is a custom version of ScanImage needed?

BakingTray interacts with ScanImage via the [ScanImage API](http://scanimage.vidriotechnologies.com/display/API/Introduction+to+the+ScanImage+API) and requires no modification (see [also here](https://github.com/SWC-Advanced-Microscopy/ScanImageAPI_Examples)).

### How does BakingTray use ScanImage?

BakingTray coordinates a tile scan over a sample by triggering ScanImage to acquire a small z stack at each tile X/Y position. The X and Y stages are moved by BakingTray and are not connected to ScanImage. The Z stack is performed using a [PIFOC](https://www.physikinstrumente.com/en/products/nanopositioning-piezo-flexure-stages/pifoc-objective-pinano-sample-scanners-for-microscopy/p-725-pifoc-long-travel-objective-scanner-200375/) controlled by ScanImage. BakingTray interacts with ScanImage to do the following:

1. Set the parameters for a fast z-stack
2. Set the number of reps of this stack
3. Set up the imaging parameters such as image size, number of microns per optical degree, etc.

The tile scan itself is performed using a [callback function](https://github.com/SainsburyWellcomeCentre/BakingTray/blob/master/code/components/scanning/%40SIBT/tileAcqDone.m) in the [SIBT class](https://github.com/SainsburyWellcomeCentre/BakingTray/tree/master/code/components/scanning/%40SIBT) that runs after z stack finishes at a single X/Y position.

## Acquisition

### Can I change the number of sections to acquire on a running acquisition?

To change the number of sections to acquire once the acquisition has started you currently need to stop the acquisition then [restart it](https://github.com/raacampbell/bakingtray_docs/tree/master/broken-reference/README.md).

### I notice substantial variability in section acquisition time in the acqLog file

Of course different sections will have different numbers of tiles should you be using the default auto-ROI feature. However, in addition to this, there are small time differences between sections even with the same number of tiles. If these differences are large, you might want to confirm that the PID loop of your stages is behaving as expected and there are not issues in settling time of the stages.

### Should I blank the scanner flyback?

If you blank the scanner flyback with amplifiers you can get rid of amplifier ringing which would otherwise create slightly annoying bright/dim alternating lines in the raw data. However, with a resonant scanner this also causes the non-imaged parts of the tile to be bleached and can create stitching artifacts later. Further, the ringing should be canceled out with the average image correction.

## Laser control

### The laser seems to connect but can't be turned on via the GUI.

As a workaround, try issuing `hBT.laser.turnOn` at the command line. This may turn on the laser then allow it to be controlled via the GUI. You could also try closing and re-opening the GUI. File an issue if you see behavior such as this.


# Gallery

The following is an example image obtained with the software. The image is obtained using tile-scanning with a 12 kHz resonant scanner. Tile illumination artifacts have been removed during image assembly by [StitchIt](https://github.com/SainsburyWellcomeCentre/StitchIt).

![](/files/-MAWC6rmLC8K-f9Hc-Im)

## Seamless 3-D volumes

BakingTray can produce seamless 3-D volumes. This is a movie of a mouse brain which was injected with a GFP viral tracer. The the grey shows background fluorescence.

{% embed url="<https://www.youtube.com/watch?v=NaDrk2N9iBg>" %}

## RGB imaging

The following movie was obtained using tdTomato, GGP, and BFP. Sample imaged at 790 nm using a 2-photon laser. Sections taken every 25 microns. Artifacts arise from the very thin sections that sometimes float between the sample and the objective.

{% embed url="<https://youtu.be/cLhQb5BEKjQ>" %}

## Tracing neurites from single cells

Moving showing single cortical neurons expressing GFP after plasmid electroporation.

{% embed url="<https://youtu.be/vBPPI2r1B1E>" %}

## Pulvinar neurons projecting to cortical area AL

These maximum intensity projections come from data generated by Ioana Gasler. They are RetroAAV cre in AL and flex mCherry in the pulvinar. Data were acquired at 2.2 x 2.2 x 10 µm. Images are max intensity projections of the full volume along different axes, with a bit of Gaussian blur for smoothing (sigma = 1 µm). The volume shown is roughly 4.7 x 3.6 x 6.0 mm (ML x DV x AP). Note that despite the relatively large step size (10 µm) between optical planes, it is easy to follow the single axons.

![Pixel size is 2.2 by 2.2 microns and data are a max intensity projection over a small number of planes.](/files/-MGOrx5DEjLGBEAZ3G0O)

![Pixel size along rows is 2.2 microns but along columns is 10 microns. Data are a max intensity projection over a small number of planes.](/files/-MGOrx5Eq4V5TFwJfuTA)

![Pixel size along rows is 10 microns but along columns is 2.2 microns. Data are a max intensity projection over a small number of planes.](/files/-MGOrx5F2vlv0iR4Q3K4)


