This repo provides a pipeline to generate high quality tetrahedral meshes of brain tissue on the cellular scale suitable for numerical simulations.
- generates high quality meshes of dense reconstructions of the neuropil
- both extracellular and intracellular space included
- automated pipeline from segmentation to mesh
- image processing steps included, to account for e.g. missing ECS from chemically fixated tissue
First, install snakemake (using conda):
conda create -c conda-forge -c bioconda -n snakemake snakemake snakemake-storage-plugin-http snakemake-executor-plugin-cluster-generic
and activate it:
conda activate snakemake
Then, run snakemake on an example configuration file, with e.g.
snakemake --configfile configfiles/cortical_mm3.yml --use-conda --cores 8
Emimesh works with .yaml configuration files (see config_files/ for examples). In one file, you specify:
- the base dataset, position and size, using webknossos or neuroglancer (example: cortical MM^3 dataset at position 225182-107314-22000)
- segmentation processing steps and meshing parameters
Then, emimesh will do the following steps for you:
- download segmented image data
- preprocess the image for meshing
- extract the surfaces of each cell
- generate a volumetric mesh of the extracted surfaces mesh and the extracellular space in between the cells with fTetWild
A simple configuration file could look like this:
name : cortical_mm3 # will only be used for naming the output folder
fixed :
raw:
cloudpath : "precomputed://gs://iarpa_microns/minnie/minnie65/seg" # cloud volume datapath
mip : 2 # resolution level (usually 0 corresponds to finest, and higher mips provides upsampled data)
position : "225182-107314-22000" # center of the dataset
processing:
operation :
- "smooth iterations=1 radius=1" # smooth the segmentation before meshing
raw:
size : [5000] # side length of the dataset (in physical dimension, usually nm)
processing:
dx : 20 # isotropic voxels size for resampling before processing
meshing:
envelopsize : [18] # maximum deviation of the tetrahdral mesh interfaces from the input surfaces (in physical dimension, usually nm).The configuration file is divided into fixed parameters (global settings) and specific blocks for raw, processing, and meshing which can be iterated over by Snakemake if provided as lists, resulting in a multiple output meshes. Single values will result in a single mesh.
Controls data download and extent.
| Option | Description |
|---|---|
cloudpath |
URI to the data source. Supports precomputed:// (cloud-volume) or webknossos URLs. |
position |
Center coordinates of the volume in x-y-z format (integer pixels). |
mip |
Resolution level. 0 is the highest resolution. Higher integers indicate downsampled versions. |
size |
Dimensions of the volume to download in physical units (nm). Can be a single integer [5000] for a cube, or "dx-dy-dz" for a bounding box (where dx,dy and dz are integer values). |
Controls general resampling and filtering.
| Option | Description |
|---|---|
dx |
Target isotropic resolution (nm). The downloaded data will be resampled to this resolution before operations are applied. |
ncells |
(Optional) Integer. If specified, only the largest N cells by volume are kept in the final mesh. |
Controls the fTetWild meshing engine.
| Option | Description |
|---|---|
envelopsize |
The "envelope" size (epsilon) for fTetWild, in nm. This defines how much the final tetrahedral mesh surface is allowed to deviate from the input surface. Larger values allow for coarser meshes with fewer elements. |
stopquality |
(Optional) fTetWild quality score (default: 10). Controls the trade-off between mesh quality and fidelity. Higher values stop optimization earlier (at the expense of mesh quality). |
A key part of the EMI-Mesh workflow is the processing block in your config file. You can define a sequential list of operations to clean, smooth, and manipulate the segmentation data before meshing. The operations are based on nbmorph and are multithreaded.
Operations are defined as a list of strings under processing: operation. Each string follows the format:
"command arg1=value1 arg2=value2 ..."
| Operation | Arguments | Description |
|---|---|---|
merge |
labels (list) |
Merges all provided labels into the first label in the list. Useful for combining fragments of the same cell. |
ncells |
ncells (int)keep_cell_labels (list, optional) |
Filters the image to keep only the N largest cells (by volume). Use keep_cell_labels to ensure specific IDs are not filtered out. |
dilate |
radius (int)labels (list, optional) |
Expands labels by the specified radius (in pixels). If labels is provided, only those specific cells are dilated. |
erode |
radius (int)labels (list, optional) |
Shrinks labels by the specified radius. If labels is provided, only those specific cells are eroded. |
smooth |
radius (int)iterations (int)labels (list, optional) |
smooths the cell boundaries using morphological opening and closing. |
removeislands |
minsize (int) |
Removes disconnected components (dust) smaller than the specified voxel count. |
You can generate a mask (ROI) based on specific cells and apply operations to that mask before applying it back to the image. This is useful for masking out areas surrounding specific cells.
| Operation | Arguments | Description |
|---|---|---|
roigenerate |
labels (list) |
Creates a binary ROI mask containing the specified labels. |
roiapply |
None | Applies the current ROI mask to the image (sets everything outside the ROI to 0/ECS). |
roi<op> |
Same as op | Applies a standard operation to the ROI mask itself (e.g., roidilate radius=10, roierode). |
1. Basic Smoothing and Cleaning Standard cleanup for a cortical volume.
processing:
operation:
- "removeislands minsize=5000" # Remove small noise
- "dilate radius=1" # Close small gaps
- "smooth iterations=1 radius=1" # Smooth boundaries
- "erode radius=1" # Create gaps between cells2. Targeting a Specific Cell (Astrocyte) Filter for 1 cell, but ensure a specific ID is kept, then smooth.
processing:
operation:
- "ncells ncells=1 keep_cell_labels='[864691136194301772]'"
- "smooth iterations=1 radius=2"
- "erode radius=1"3. Complex ROI Manipulation (Capillary) Merge fragments, clean noise, then create a large masked area around a specific capillary cell to exclude distant neighbors.
processing:
operation:
# Merge fragmented labels into one ID
- "merge labels='[864691136534887842, 864691135476973891]'"
# Clean up
- "removeislands minsize=5000"
- "dilate radius=5"
- "smooth iterations=2 radius=4"
- "erode radius=1"
# Create a mask based on the main capillary label
- "roigenerate labels='[864691136534887842]'"
# Expand the mask significantly
- "roidilate radius=80"
# Apply mask (delete everything outside the expanded capillary area)
- "roiapply"The output consists of the following directories:
- raw: The downloaded segmentation as in
.vtkformat, suitable for e.g. paraview - processed: The processed image in
.vtkformat - surfaces: The surfaces of the extracted cells in
.plyformat, again suitable for visualization with paraview or usage in other meshing software - meshes: The generated volumetric meshes in
.xdmfformat, containing labels for the extracellular space (label 1) and increasing integer values (2,..., N) for all cells. A mapping between the labels and the original cell id in the base segmenation is provided in theprocessed/.../imagestatistics.ymlfile.
