This Python script processes brain atlas registration masks generated by BrainGlobe to optimize them for import into Imaris. It adjusts the level of detail of atlas subdivision, removes small disconnected regions, and ensures compatibility with Imaris Import Segmentations/Labels function.
The mask processing pipeline addresses several problems:
- Hierarchy simplification: Combines detailed brain regions into larger parent regions (for example, it can merge all hypothalamic nuclei into one big region labeled as 'hypothalamus')
- Fragment cleanup: Removes disconnected small regions, that make working with Imaris unusable
- ID compatibility: Ensures region IDs fit within the selected image type (16-bit)
- Brain region name-ID mapping: Creates a csv with mapping of region IDs to corresponding names
import tifffile # TIFF image I/O
from brainglobe_atlasapi import BrainGlobeAtlas # Atlas data access
from scipy.ndimage import generate_binary_structure # Morphological operations
from tkinter import Tk, filedialog # GUI file selection
import os # File system operations
import numpy as np # Numerical operations (imported in functions)
import pandas as pd # Data manipulation (imported in functions)conda activate brainglobe_env
pip install tifffile scipy pandas tkinterThese file names are expected by the other parts of the pipeline, so do not change them unless you know what you are doing.
input_mask_filename = "registered_atlas_original_orientation.tiff"
output_mask_filename = "adjusted_mask.tiff"
whole_brain_mask_filename = "whole_brain_mask.tiff"
output_label_csv = "used_region_ids.csv"
output_fragment_csv = "region_fragments_with_sizes.csv"Change atlas_name if you are using different atlas.
atlas_name = "perens_lsfm_mouse_20um"
min_fragment_size = 50 # Fragments smaller than this amount of voxels will be discardedThese parameters define the level of detail required for individual brain areas. Adjust based on which regions you are interested in. The finer the details preserved, the more difficult it will be to load them to Imaris. All regions not belonging to any of the listed regions will be kept on the finest level of detail, which is generated by BrainGlobe.
For each of the listed regions, its subdivisions will be combined together (for example, all hypothalamus parts will be combined into one 'hypothalamus' region).
regions_to_flatten = [
"fiber tracts", # White matter tracts
"VS", # Ventricular system
"CB", # Cerebellum
"HB", # Hindbrain
"MB", # Midbrain
"TH", # Thalamus
"HY", # Hypothalamus
"STR", # Striatum
"PAL", # Pallidum
"CTXsp" # Cortical subplate (includes amygdala)
]Preserves first-level subdivisions (e.g., primary visual cortex, primary motor cortex) while merging finer subdivisions (layers, subareas).
regions_to_flatten_on_level_1 = [
"Isocortex", # Isocortical areas
"OLF" # Olfactory areas
]All voxels belonging to the listed regions will be marked as background and thus excluded from further processing. It is advisable to exclude highly fragmented regions, such as fiber tracts, unless you are interested in them. That is because these will produce a lot of tiny objects in Imaris, which will make it more difficult to work with.
regions_to_exclude = [
"fiber tracts", # Removed due to thin, fragmented structure
"root" # Non-informative parent region
]Rationale:
- Fiber tracts: Often fragment into many disconnected pieces during registration
- Root: Generic parent region that doesn't provide anatomical information
Increasing the level will preserve more detailed subdivisions.
# Keep more detailed subdivisions
regions_to_flatten_on_level_2 = ["Isocortex"]
simplified_mask = flatten_descendants_of_level(
simplified_mask, atlas, regions_to_flatten_on_level_2, level=2
)# More aggressive cleanup (removes also larger fragments)
min_fragment_size = 100
# More conservative cleanup (keeps smaller fragments)
min_fragment_size = 20Considerations:
- Larger values: Cleaner results, may remove legitimate small structures
- Smaller values: Preserves detail, may keep artifacts
- Recommended range: 20-100 voxels depending on resolution
- Completed registration in Napari/BrainGlobe with
registered_atlas_original_orientation.tiffin working directory - Properly configured BrainGlobe environment
- Quality review: Examine output masks in ImageJ or Napari
- Imaris import: Use adjusted mask for surface generation
- Label assignment: Apply region labels using Imaris XTension
- Input:
registered_atlas_original_orientation.tiff(from BrainGlobe registration) - Output: Multiple files for Imaris import and analysis
- Following step: Imaris import and label assignment (Step 3 of pipeline)
path = askdirectory(title='Select Folder')
if not path:
print("No folder selected. Exiting.")
exit(1)
os.chdir(path)Process:
- Opens GUI dialog for folder selection
- Sets working directory to selected folder
- Expects to find input mask file in this directory (with name specified by
input_mask_filename)
atlas = BrainGlobeAtlas(atlas_name)
mask = tifffile.imread(input_mask_filename)Process:
- Downloads/loads specified atlas from BrainGlobe
- Reads the registered mask TIFF file
- Validates file format and dimensions
whole_brain_mask = create_whole_brain_mask(mask)Purpose: Creates a binary mask of the entire brain region for:
- Quality control and visualization
- Downstream analysis requiring brain boundaries
- Validation of registration quality
simplified_mask = flatten_regions(mask, atlas, regions_to_flatten)
simplified_mask = flatten_descendants_of_level(simplified_mask, atlas, regions_to_flatten_on_level_1, level=1)
simplified_mask = exclude_regions(simplified_mask, atlas, regions_to_exclude)Process:
- Complete flattening: Merges all subdivisions of specified regions into the parent region
- Level-specific flattening: Preserves subdivisions up to the specified level
- Region exclusion: Removes specified regions (sets to 0)
structure = generate_binary_structure(rank=3, connectivity=1)
cleaned_mask, fragment_info = remove_small_fragments(simplified_mask, min_fragment_size, structure, atlas)Process:
- Connectivity: Uses 6-connectivity (face-connected voxels only)
- Size filtering: Removes fragments smaller than
min_fragment_size - Documentation: Records all fragments and their fates
Connectivity choice: Face-connectivity (connectivity=1) is used because it better matches Imaris segmentation behavior.
adjusted_mask, id_remap, new_id_to_old_id = remap_large_values(cleaned_mask)Purpose: Ensures compatibility with 16-bit integer formats:
- Problem: Some atlas IDs exceed 65,535 (uint16 maximum)
- Solution: Maps large IDs to available smaller IDs
- Preservation: Maintains bidirectional mapping for reference
The pipeline generates multiple output files for different purposes:
- Format: 16-bit TIFF
- Content: Processed mask with simplified regions
- Use: Import into Imaris for visualization
- Format: 8-bit TIFF
- Content: Binary mask of entire brain
- Use: Quality control, boundary visualization
- Columns:
region_id,region_name,region_acronym - Content: All regions present in final mask
- Use: Imaris label import, analysis reference
- Columns:
region_id,region_name,fragment_index,fragment_size_voxels,removed - Content: Complete fragment analysis
- Use: Quality control, processing validation