Pipeline breakdown:

For processing a wholebrain dataset, the pipeline is split into 5 sections. These sections are listed below along with the functions that belong to each section:


Part 1: Setup pipeline

Part 2: Alignment (W)

Part 3: Registration

Part 4: Segmentation, duplicate cleanup, & forward warping

Part 5. Dataset manipulation and plotting

Below is a walkthrough of each of these functions and the pipeline as a whole using an example whole brain dataset. Feel free to use the function links above to skip sections!



Part 1: Setup pipeline

This sections sets up analysis parameters, sorted image paths, and generates savepaths and directories for the rest of the pipeline.


Step 1.

setup_pl() This function asks the user for setup information. Based on input from the user, the function returns a list of parameters for either a whole or partial brain analysis.

# Scroll to the details section of the help page to see the setup parameters
?setup_pl()

# Run setup_pl, enter parameter information to the console, 
# and store the output list into a variable named setup

setup <- setup_pl()

# Check or modify your setup parameters 
setup <- setup_pl(setup)

# Note: Whenever a different user works on analyzing the same dataset,
# run the above command to change user initials. This will keep track of
# who did what. 

Tips: When providing folder paths, do not put quotes around the path to the console input.

For convention, sequential image numbers are z image numbers, even for a partial brain analysis. Z image number should start at 1 and end at the number of images. Image files should start indexing at 1 in the filenames to match image number.

For a whole brain analysis, the first and last atlas plates must be qualitatively aligned with the first and last z image numbers. Note that the setup$internal_ref_z, setup$regi_AP, setup$regi_z parameters are not user modifiable and will be NULL until thechoice() or interpolate() functions are run.

Additionally, there are a few default pipeline parameters for whole brain analysis:

The above coordinates correspond to PFC, NAc, antHyp, start of HIP, posterior Hyp, VTA, and the PAG, respectively. These coordinates will be the atlas plates used to “calibrate” to internal z images. They’ll be used to interpolate and match the z images of remaining atlas plates. They were chosen because:

  1. Based on our experience, they contain easy internal region landmarks that can be consistently identified by different users
  2. They are somewhat evenly spaced throughout the brain.

However, these coordinates are user modifiable to account for user preference and varying AP ranges of imaging datasets. If you are using this pipeline for the first time, I recommend you take the default values.

The console code below shows the setup list I am using:

# Check setup list

> setup<- setup_pl(setup)

Your animal ID         :  1602
Your initials          :  MJ
Your registration path :  D:/output_R15_1602_SG_Rein_NoTest_coronal/R15_1602_SG_Rein_NoTest_coronal_final_C02_betterrotation
Your segmentation path :  D:/output_R15_1602_SG_Rein_NoTest_coronal/R15_1602_SG_Rein_NoTest_coronal_final_C01_betterrotation
Your output path       :  D:/SMART_example_data/output
Your z spacing         :  0.0025
Your registration step :  0.1
Your segmentation step :  1
Your first AP          :  2.82
Your first z           :  200
Your last AP           :  -4.77
Your last z            :  2925
Your internal reference AP coordinates:  1.91 1.1 -0.42 -0.93 -1.94 -2.44 -2.95 -3.45 -3.96
Please review your setup information above:
Do you want to change any settings: Y/N?
>


Step 2. im_sort() User friendly way to sort images from the registration channel. Asks for user input to account for flexible naming conventions for images.

# Sort images and store them 

# There will be user walk through for the 'separator' 
# and 'position' information necessary to sort images 
setup <- im_sort(setup, extension = "tif")

# Note: Setting the position argument will skip the user walkthrough. 
# e.g.
setup <- im_sort(setup, extension = "tif", position = 9)

# Check image_paths
setup$image_paths


Step 3.

get_savepaths() Create standardized save directories based on the setup information from setup_pl(). setup is returned with setup$savepaths filled containing savepaths to subfolders in the output folder.

# Create savepaths and generate data subdirectories automatically 
setup <- get_savepaths(setup)

# Check the output folder to see the subdirectories created!

# Show savepaths generated
setup$savepaths

# To save the global environment at any time during an analysis session run: 
save.image(setup$savepaths$envir_savepath)

# Going to the R_data folder in the output folder and clicking on the 
# .RData folder by date will revert the global environment back to a previous session.
# Saving everyday will prevent you from losing more than a day's worth of work.

Tip: rerun the save.image() expression to update the global environment savepath every day.

Below shows my console output for my savepaths variable:

# Update and show savepaths

> setup <- get_savepaths(setup)
> setup$savepaths
$`envir_savepath`
[1] "D:/SMART_example_data/output/R_data/Animal_1602_2019-01-20_MJ.RData"

$out_reference_aligned
[1] "D:/SMART_example_data/output/Reference_aligned"

$out_RC_brain_morph
[1] "D:/SMART_example_data/output/RC_brain_morph"

$out_auto_registration
[1] "D:/SMART_example_data/output/Registrations_auto"

$out_registration
[1] "D:/SMART_example_data/output/Registrations_manual"

$out_registration_warps
[1] "D:/SMART_example_data/output/Registration_warps"

$out_segmentation_warps
[1] "D:/SMART_example_data/output/Segmentation_warpimages"

$out_segmentation_schem
[1] "D:/SMART_example_data/output/Segmentation_schematics"

>


Part 2: Alignment (W)

This section is necessary for whole brain datasets only. Users first “calibrate” the reference atlas plates with their appropriate z image number by running choice() and playing the choice game. Based on the aligned reference plates, the user can match all remaining atlas plates with an interpolated z image using interpolate().


Step 4.

choice() (W) User friendly way to play the wholebrain choice game to align internal reference atlas plates. Automatically saves images of chosen aligned images in the folder specified by setup$savepaths$out_reference_aligned.

Below is my initial console output when I runchoice() with my setup variable.

# Run the choice game and save the aligned 
# z reference number back into the setup list:

> setup <- choice(setup, filetype = "tif") # save chosen images as tifs
Play the choice game!
Your reference AP is 1.91 
Your current image sampling choice_step is  200 

Which image matches best?
Enter 1, 2 or 3:

How the choice game works:

The choice game will cycle through the internal reference atlas plates (represented below by dotted vertical lines). Three choice windows will popup for each reference AP coordinate, corresponding to choices 1,2 or 3, respectively. The user simply compares the corresponding atlas plate with the 3 choice windows and enters the best qualitative match.

Internal reference atlas plates

Internal reference atlas plates

The middlemost window (choice 2) is SMART’s best guess at the z image best aligned with the atlas coordinate based on the first and last aligned atlas plates (represented above by solid vertical lines).

Display and prompt

Display and prompt

Note: The default positions the windows pop up on screen can be set by the xpos argument.

The current choice_step indicates how many z images the anteriormost (choice 1) or posteriormost (choice 3) images are from the middlemost image (choice 2). Entering 1, 2 or 3 into the console has three outcomes:

  1. Choice 1 The anteriormost image becomes the new choice 2 on the next choice option.
  2. Choice 2 On the next choice option, there is a smaller choice_step on the left and right images. Choosing this option will progressively “zoom in” on the choice_step options until the steps can’t get smaller. The choice game will then move on to the next atlas coordinate. By default, the smallest step is 10.
  3. Choice 3 The posteriormost image becomes the new choice 2 on the next choice option.

Note: the choice_step progression is a user modifiable argument.

Midpoint quality check

Midpoint quality check

Once all the internal references atlas coordinates have been aligned, you can cycle through the midpoint AP coordinates of the aligned references as a quality check (represented above with black arrows). After comparing midpoints, any unsatisfactory midpoints become another internal reference point. The choice game automatically is replayed for those midpoints.

Below shows my code to run the midpoint check:

# Run the midpoint check 
> setup <- choice(setup, midpoint = TRUE, filetype = "tif")

The following image represents the console and popup window display during the midpoint check.

Midpoint quality check display

Midpoint quality check display


Below are my internal reference AP coordinates and z numbers after runningchoice() and checking midpoints with my analysis setup:

# Check internal reference AP numbers
> setup$internal_ref_AP
[1]  1.9060687  1.0969084 -0.4202672 -0.9259924 -1.9374427 -2.4431679 -2.9488931 -3.4546183 -3.9603435

# Check matched image z numbers
>  setup$internal_ref_z
[1]  526  850 1492 1658 1950 2141 2402 2623 2723


If you are unsatisfied later with a few internal reference coordinate alignments, you can replay the choice game for just those points by setting them as a vector to the [touchup] argument. The code below replays the choice game for only coordinates 1.91 and -0.42 (double digit entries are fine):

# redo internal AP points 1.91 & -0.42
> setup <- choice(setup, touchup = c(1.91, -0.42 ))


brainmorph() (W) Generate a brain morph plot showing areas of relative expansion or compression along the AP axis compared to the Allen Mouse Brain Atlas AP coodinates (normalized to 1). The reference atlas points used to generate the morph plot are plotted in red. Setting saveplot = TRUE will save the brain morph into the data folder designated by setup$savepaths$out_RC_brain_morph

# Generate brainmorph. 
brainmorph(setup, saveplot = FALSE)
Brainmorph plot

Brainmorph plot


Step 5.

interpolate() (W) This function interpolates all corresponding z and AP values for atlas plates that are not reference plates.

# Interpolate all remaining atlas plates and their z number
setup <- interpolate(setup)

Now checking the setup list will show all matched internal AP plates and z numbers:

> setup$regi_AP
 [1]  2.81637405  2.71522901  2.61408397  2.51293893  2.41179389  2.31064885  2.20950382  2.10835878  2.00721374
[10]  1.90606870  1.80492366  1.70377863  1.60263359  1.50148855  1.40034351  1.29919847  1.19805344  1.09690840
[19]  0.99576336  0.89461832  0.79347328  0.69232824  0.59118321  0.49003817  0.38889313  0.28774809  0.18660305
[28]  0.08545802 -0.01568702 -0.11683206 -0.21797710 -0.31912214 -0.42026718 -0.52141221 -0.62255725 -0.72370229
[37] -0.82484733 -0.92599237 -1.02713740 -1.12828244 -1.22942748 -1.33057252 -1.43171756 -1.53286260 -1.63400763
[46] -1.73515267 -1.83629771 -1.93744275 -2.03858779 -2.13973282 -2.24087786 -2.34202290 -2.44316794 -2.54431298
[55] -2.64545802 -2.74660305 -2.84774809 -2.94889313 -3.05003817 -3.15118321 -3.25232824 -3.35347328 -3.45461832
[64] -3.55576336 -3.65690840 -3.75805344 -3.85919847 -3.96034351 -4.06148855 -4.16263359 -4.26377863 -4.36492366
[73] -4.46606870 -4.56721374 -4.66835878 -4.76950382


> setup$regi_z
 [1]  200  236  272  309  345  381  417  454  490  526  566  607  648  688  728  769  810  850  893  936  978 1021
[23] 1064 1107 1150 1192 1235 1278 1321 1364 1406 1449 1492 1525 1558 1592 1625 1658 1687 1716 1746 1775 1804 1833
[45] 1862 1892 1921 1950 1988 2026 2065 2103 2141 2193 2245 2298 2350 2402 2446 2490 2535 2579 2623 2643 2663 2683
[67] 2703 2723 2748 2774 2799 2824 2849 2875 2900 2925


Part 3: Registration

This section automates looping through through and registering all atlas plates to images from the registration channel. It also allows for easy modification of registrations.


registration2() (O) Provides a user friendly interface to alter registrations. It retains the same arguments from the registration() function in wholebrain. This function may be useful for those who already have their own established analysis pipelines. Check out the function help page for more details.

Registration interface

Registration interface

The schematic above illustrates the user-friendly console interface that allows for modification of the correspondence plates on a given atlas plate. The regi_loop() function integrates this user-friendly registration interface with the pipeline.


Step 6.

regi_loop() User friendly function to alter atlas to image registration. When run with defaults, this function will automatically create a list in the global environment called regis. It will loop through the atlas plates according to the user preferences. The user also has the option to save the global environment after every manual registration.

# Example run of automated registration loop

# Create filter for registration
filter<-structure(list(alim = c(50, 50),
                           threshold.range = c(50000, 60000L),
                           eccentricity = 999L,
                           Max = 1000,
                           Min = 150,
                           brain.threshold = 270L,
                           resize = 0.25,
                           blur = 7L,
                           downsample = 2))

# Run the autoloop
regi_loop(setup, autoloop = TRUE, filter = filter)

Note: The function filter_loop() allows the user to modify the filter for registration or segmentation and loop through the references plates to check filter adjustments in images across the brain.

There are four different loop options:

  1. autoloop = TRUE runs wholebrain’s first pass at registering all atlas plates. Registrations are stored in the Registrations_auto folder. This is useful to check the quality of registrations across all atlas plates using current filter settings.
  2. reference = TRUE loops through reference atlas plates only and displays the console interface.
  3. The touchup argument is designed to edit a subset of atlas plates that have been previously registered. This argument requires referencing atlas plate numbers, not AP coordinates. Plate numbers can be easily found in the file names of the images saved to the ‘Registrations_manual’ folder in the output folder.
  1. Setting all the arguments above to FALSE will loop through all atlas plates and display the console interface.

Tip: Save the global environment after every 2-3 registrations. The save time lengthens significantly as more registrations are stored in the regis list.

Once the regi_loop() function has been run for the first time, the regis argument must be set to the regis list automatically generated in the global environment.

For example:

# Loop through and modify only reference atlas plates
regi_loop(setup, regis = regis, filter = filter, reference = TRUE)

Below is an example of a registration before and after manual improvement:

After auto-registration

After auto-registration

After registration correction

After registration correction



Part 4: Segmentation, duplicate cleanup, & forward warping

This section loops through all the images of the segmentation channel and automates the forward looping process. At the end of this section, you will have a mapped dataset!


Step 7.

filter_loop() This function takes a registration or segmentation filter and loops through all images in a partial brain or just the reference images in either the registration or segmentation channel. The wholebrain::segment() function is used to display the segmentation output. There is a console menu option for the user to adjust filter parameters if they need.

# Check and modify filter settings in the segmentaion channel
filter <- filter_loop(setup, channel = "seg")

An explanation of the filter parameters according to WholeBrain documentation is provided below:


Step 8.

seg_loop() This function loops through the z images in the segmentation folder path. For a whole brain, every N images is segmented, where N is equal to setup$seg_step. For a partial brain, all the images in setup$regi_z are segmented.

# Run segmentation loop and store the output
segs <- seg_loop(setup, filter)

Note: If the imaging dataset is large, steps 8, 9, & 10 will be time intensive processes. Processing time will be printed after each of these functions are finished.


Step 9.

clean_duplicates() (W) Duplicate cell count clean up of segmentation output from the seg_loop() function. This step is only necessary for large imaging datasets where the z step size is smaller than the width of a cell body.

# Clean duplicate cell counts 
segs <- clean_duplicates(setup, segs, z_thresh = 10, compare_depth = 200)

# z_thresh - Threshold (in um) in the z-plane for the maximum z distance 
# before a cell is counted as another cell.

# compare_depth -  Comparision depth in (um). Compare a single image with adjacent 
# images up to 200 um posterior.


Step 10.

forward_warp() (W) Loop through all segmented cells and perform forward warp loop back onto atlas space using registration and segmentation data. There are user options for plotting a schematic plot and saving forward warp images. The function will automatically interpolate AP coordinate values of z images in between atlas plates and assign them to the dataset.

# Perform forward warp
dataset <- forward_warp(setup, segs, regis)

Below are representative forward warp and schematic images:


Forward warp image


Schematic plot

Note: forward_warp() will automatically clean up any cell counts that aren’t assigned a region ID.



Part 5: Dataset manipulation and plotting:

Following Step 10, there are no more steps in the pipeline. The remaining functions are designed for easy manipulation and plotting of the dataset.


get_rois() (O) Allows the user to enter a character vector of Allen Mouse Brain Atlas abbreviations of regions of interest (ROIs). A subset of the dataframe from the wholebrain dataset of just the ROIs (and their subregions) are returned.

get_rois() is especially useful in plotting cell count tables of regions of interest:

# Get dataset of just rois
rois <- get_rois(dataset, rois = c("ACB", "CEA", "BLA", "HIP"))

# Plot region cell counts in a table
quartz()
wholebrain::dot.plot(rois)
Region plot

Region plot


get_sunburst() (O) Generate a sunburst plot using a forward warped dataset.

# Plot sunburst plot using the get_sunburst() function
SMART::get_sunburst(dataset)
Legend

Note: By setting the rois argument, the sunburst will display only ROI data. If the parent argument is set to FALSE, the base layer in sunburst will be the first ROI.


get_tree() (O) Create a dataframe of hierarchical region cell count data.

The code below generates a dataframe of the hierarchy tree for the hypothalamus:

# Hierarchical dataframe of just the hypothalamus
tree <- get_tree(dataset, rois = "HY")
View(tree)

Note: this dataframe may be useful for generating other heirarchical plots such as treemaps.


glassbrain2() (O) A modified version of wholebrain::glassbrain(). New options include:

  1. Gives the user an option to turn off the “jitter” in cell placement in original glassbrain function (the jitter gives a more space filled look).

  2. Does not show the glass brain display when high.res is set to “OFF” (otherwise set to TRUE or FALSE). Setting high.res to TRUE or FALSE will render a high or low resolution atlas boundary

# Generate rgl object and plot glassbrain without 3D atlas boundaries
glassbrain <- glassbrain2(dataset, high.res = "OFF", jitter = FALSE) 

# visualize glass brain 
glassbrain
RGL model

You must enable Javascript to view this page properly.


Drag mouse to rotate model. Use mouse wheel or middle button to zoom it.

Object written from rgl 0.99.16 by writeWebGL.

Tip: Combine the get_rois() function output with glassbrain2() to get a glass brain of just ROIs.


get_table() (O) Generates a dataframe showing region acronyms, their full name, hierachical paths, total cell counts, left and right counts, and cell count percentages.

# Example usage:
# Get data table displaying cell counts from Ammon's horn
table <- get_table(dataset, rois = "CA", base = "HIP")
View(table)

# Setting the base argument to "HIP" changes the count percentage to be out of the entire hippocampal formation
# Change base to "CA" bases the percentage counts off cell counts in Ammon's horn exclusively
# Change base and rois to "grey" to get all cell counts of grey matter in the brain


The table below is representative of the dataframe displayed:

Region Name Path Count Left Right Left_Right_Ratio Percentage
HIP Hippocampal region HIP 6200 3258 2942 1.11 100%
CA Ammon’s horn HIP-CA 3324 1759 1565 1.12 53.61%
CA2 Field CA2 HIP-CA-CA2 48 30 18 1.67 0.77%
CA3 Field CA3 HIP-CA-CA3 1372 751 621 1.21 22.13%
CA1 Field CA1 HIP-CA-CA1 1904 978 926 1.06 30.71%
CA2slm Field CA2, stratum lacunosum-moleculare HIP-CA-CA2-CA2slm 12 6 6 1.00 0.19%
CA2sr Field CA2, stratum radiatum HIP-CA-CA2-CA2sr 18 11 7 1.57 0.29%
CA2so Field CA2, stratum oriens HIP-CA-CA2-CA2so 10 7 3 2.33 0.16%
CA2sp Field CA2, pyramidal layer HIP-CA-CA2-CA2sp 8 6 2 3.00 0.13%
CA3sr Field CA3, stratum radiatum HIP-CA-CA3-CA3sr 322 183 139 1.32 5.19%
CA3so Field CA3, stratum oriens HIP-CA-CA3-CA3so 454 245 209 1.17 7.32%
CA3slm Field CA3, stratum lacunosum-moleculare HIP-CA-CA3-CA3slm 4 1 3 0.33 0.06%
CA3slu Field CA3, stratum lucidum HIP-CA-CA3-CA3slu 78 52 26 2.00 1.26%
CA3sp Field CA3, pyramidal layer HIP-CA-CA3-CA3sp 514 270 244 1.11 8.29%
CA1sp Field CA1, pyramidal layer HIP-CA-CA1-CA1sp 314 152 162 0.94 5.06%
CA1slm Field CA1, stratum lacunosum-moleculare HIP-CA-CA1-CA1slm 921 458 463 0.99 14.85%
CA1so Field CA1, stratum oriens HIP-CA-CA1-CA1so 191 113 78 1.45 3.08%
CA1sr Field CA1, stratum radiatum HIP-CA-CA1-CA1sr 478 255 223 1.14 7.71%