A Julia package for exploring the neurons and connections of the Drosophila optic lobe, based on the FlyWire connectome (v783 proofreading).
This package accompanies two visual system papers in the FlyWire paper package:
- Matsliah, Yu, et al., Neuronal parts list and wiring diagram for a visual system, Nature 634:166-180 (2024)
- Seung, Predicting visual function by interpreting a neuronal wiring diagram, Nature 634:113-123 (2024)
The package provides easy access to:
- 740 visual cell types (230 intrinsic + 510 boundary types)
- Synaptic connectivity matrices at cell and type levels
- Cell morphology and spatial coordinates
- Analysis tools and visualization utilities
All data is automatically downloaded from the FlyWire Codex and processed into convenient Julia data structures.
julia> import Pkg
julia> Pkg.add(url = "https://github.com/hsseung/OpticLobe.jl")
julia> using OpticLobeNote: The first time you load the package, it will automatically download ~350MB of data files. You may see "waiting for IO to finish" messages, which can be ignored.
The package supports two synapse detection methods:
- Princeton (default): Latest synapse predictions with improved accuracy
- Buhmann: Original predictions from Buhmann et al. (2021)
# Switch to Buhmann synapses
set_default_synapses("Buhmann") # Restart Julia to take effect
# Load both versions simultaneously (uses more memory)
enable_both_synapses(true) # Restart Julia to take effectAfter enabling both versions, access them as follows:
W_Princeton[cellid1, cellid2] # Princeton synapses
W_Buhmann[cellid1, cellid2] # Buhmann synapses
W[cellid1, cellid2] # Default version (Princeton unless changed)You can check which synapse version is currently active:
# Using internal variables (quick check)
OpticLobe.default_synapses # "Princeton" or "Buhmann"
OpticLobe.load_both # true if both versions loaded, false otherwise
# Using Preferences.jl (standard approach)
using Preferences
load_preference(OpticLobe, "default_synapses") # "Princeton" or "Buhmann"
load_preference(OpticLobe, "load_both_synapses") # true or falseNote: The examples below show approximate output. Numbers may vary due to updated synapse predictions and cell type annotations in newer versions.
IDs of five Tm1 cells.
julia> first(type2ids("Tm1"), 5)
5-element Vector{Int64}:
720575940599333574
720575940603884512
720575940604009062
720575940604094240
720575940604151520Top ten target cells of 720575940599333574, with number of synapses.
julia> first(sort(W[Name(720575940599333574), :], rev=true), 10)
10-element Named SparseArrays.SparseVector{Int32, Int32}
cellid │
───────────────────┼───
720575940620875399 │ 57
720575940629884688 │ 39
720575940616048757 │ 38
720575940615102003 │ 29
720575940611830245 │ 27
720575940622106996 │ 27
720575940619661648 │ 25
720575940629129692 │ 22
720575940639008319 │ 21
720575940626667928 │ 20Cell type of 720575940620875399 (top cell in the list above).
julia> ind2type[id2ind(720575940620875399)]
"Pm05"Top ten target cell types of 720575940599333574, with number of synapses.
julia> first(sort(Wct[Name(720575940599333574), :], rev=true), 10)
10-element Named SparseArrays.SparseVector{Int32, Int32}
celltype │
──────────┼────
Pm03 │ 131
Pm08 │ 86
Pm02 │ 72
Pm05 │ 57
T2a │ 41
LMa5 │ 29
T5a │ 29
T3 │ 26
Tm21 │ 26
Tm4 │ 22Number of synapses from cell type Tm1 to cell type TmY4:
julia> Wtt["Tm1", "TmY4"]
5068Top ten intrinsic cell types targeted by cell type Tm1:
julia> first(sort(Wtt["Tm1", intrinsictypes], rev=true), 10)
10-element Named SparseArrays.SparseVector{Int32, Int32}
celltype │
──────────┼──────
Pm03 │ 78694
Pm02 │ 70095
Pm08 │ 49431
T3 │ 35806
T2a │ 35162
Pm05 │ 29965
Tm21 │ 21059
Y3 │ 20896
LMa5 │ 17871
Pm06 │ 17143OpticLobe uses two different cell identifiers:
- Cell ID: FlyWire root IDs (64-bit integers like
720575940599333574) that uniquely identify cells in the FlyWire dataset - Cell Index: Sequential integers (1, 2, 3, ...) used internally for array indexing and matrix operations
Conversion functions:
ind2id,id2ind- Convert between cell indices and FlyWire root IDsind2type- Map cell indices to cell type namesid2pq- Map cell IDs to spatial coordinates (hexagonal p,q system)
These are vectors of strings containing cell type names:
intrinsictypes(230) - Neurons intrinsic to the optic lobeboundarytypes(510) - Visual projection and centrifugal neuronsothertypes(7805) - All other cell types (central brain, etc.)visualtypes- Combined intrinsic + boundary types (740 total)alltypes- All cell types in the dataset
All connectivity matrices are NamedArray objects that can be indexed by either position or name using Name(). For example, W[Name(720575940599333574), Name(720575940620875399)] or Wtt["Tm1", "Dm3v"]. The core connectivity data is stored as synapse counts (Int32 values) representing the number of synaptic connections between neurons.
Cell-to-cell connectivity:
W- Full synaptic weight matrix (sparse, ~130K × 130K cells).W[i, j]is the number of synapses from neuronito neuronj.
Cell-to-type and type-to-cell connectivity:
Wct- Cell-to-type connectivity:Wct[c, t]gives total synapses from cellcto typetWtc- Type-to-cell connectivity:Wtc[t, c]gives total synapses from typetto cellc
Type-to-type connectivity: Matrices that summarize connections between cell types:
Wtt- Type-to-type connectivity:Wtt[pretype, posttype]is raw synapse counts.infraction,outfraction- Normalized versions ofWtt(0-1 scale).inmean,outmean- Alternative normalization ofWttgiving mean synapses per cell of a type.importance- Connection importance:max(infraction, outfraction)for each connection.inrank,outrank- Rank ordering of connections by strength (intrinsic types only).
Boolean matrices that encode which cells belong to which types. These sparse matrices enable efficient filtering and selection of cells by type membership:
A- Boolean matrix assigning cells to types. whereA[c, t]istrueif cellcbelongs to typet.Ai- Submatrix ofAcontaining only intrinsic types (cells × intrinsic types).
The visual system types are organized in a three-level hierarchy: classes → families → individual types. This hierarchical organization reflects functional and anatomical relationships:
class2families- Maps 5 visual classes ("receptor", "columnar", "interneuron", etc.) to their constituent type familiesfamily2types- Maps type families ("Tm", "Dm", "R7-8", etc.) to individual cell types within each family
Basic functions for exploring connectivity patterns and cell properties:
toppre(celltype; nresults=15, sort=:in, values=:fraction)- Top presynaptic partners of a cell typetoppost(celltype; nresults=15, sort=:out, values=:fraction)- Top postsynaptic partners of a cell typetype2ids(typename; side="right")- Get all cell IDs belonging to a cell typeshowall(vector)- Display all elements of a named vectorinmaps(paths)- Convert connectivity matrix to spatial input maps (receptive fields)outmaps(paths)- Convert connectivity matrix to spatial output maps (projective fields)
Functions for analyzing multi-step synaptic pathways with hemisphere-specific filtering. All functions support a side parameter (default: "right") to restrict analysis to cells in a specific hemisphere, which is essential for studying lateralized visual processing:
tracetypes(celltypes; side="right")- Multi-step connectivity through cell type sequencetracebacktypes(celltypes; side="right")- Like tracetypes but with normalized connectivitypreimage(pretype, posttype; side="right")- Spatial map of presynaptic inputs by typeprepreimage(prepretype, pretype, posttype; side="right")- Two-step presynaptic maps
Functions for viewing cells in external tools and preparing data for plotting. The FlyWire integration functions automatically detect your environment (Jupyter vs REPL) and adapt their behavior accordingly:
codex_open(cellids; version=783)- Open cells in FlyWire Codex browser (works in both Jupyter and REPL)ng_open(cellids; version=783, darkmode=false)- Open cells in Neuroglancer 3D viewer (works in both Jupyter and REPL)ng_open(idlists; version=783, names=nothing, darkmode=false)- Open multiple segmentation layers for comparing cell groupsng_hyper(cellids; anchor, version=783, darkmode=false)- Create clickable Neuroglancer hyperlinks (Jupyter) or print URLs (REPL)ng_hyper(idlists; anchor, names=nothing, version=783, darkmode=false)- Create hyperlink with multiple segmentation layersstrings2ticks(strings)- Convert string vector to (positions, labels) for plot tick marks
Tools for working with the hexagonal column coordinate system of the optic lobe and creating spatial visualizations. The optic lobe uses a hexagonal lattice where each column has (p,q) coordinates:
id2pq[cellid]- Map cell IDs to hexagonal (p,q) column coordinatespq2column[p, q]- Map hex coordinates to column IDs (right hemisphere only)crop(image, center, radius; sat)- Extract square region from image centered at coordinatessquare2hex(square)- Convert square array to hexagonal shape by masking cornersrect2hex(rect; hexelsize, pointannotation)- Display rectangular array on hexagonal latticemontage(images; hexelsize, labels, ellipses, ...)- Create grid layout of hexagonal eye mapstriad(celltype)- Generate spatial triad visualization for cell type- Hexagonal visualization tools in
hexgraphicsmodule
The optic lobe uses a hexagonal lattice coordinate system (known as "Zhao's eye coordinates") where each column has (p,q) coordinates. The coordinate system is defined as follows:
Anatomical Orientation (for right eye):
dorsal
^
|
anterior <-+-> posterior
|
v
ventral
Hexagonal Grid Axes:
+pdirection is anterodorsal+qdirection is posterodorsal+vdirection is dorsal+hdirection is posterior
+p +v +q
\ | /
\ | /
\ | /
\|/
+----- +h
Key Properties:
- The
+pand+qdirections are approximately 90° apart (120° on perfect hexagonal grid) - Column coordinates are integers representing discrete positions on the lattice
- Only the right hemisphere is fully mapped in
pq2column - Missing values indicate positions without columns (gaps in the eye)
Reference: This coordinate system is defined in Figure 2 of Arthur Zhao et al. 2022. The coordinate transformations and visualizations use this system throughout the package.
Morphological measurements for individual cells. These are NamedArrays indexed directly by FlyWire cell IDs, with measurements converted from nanometers to micrometers for convenience:
cell_length[cellid]- Cable length of cell in micrometerscell_area[cellid]- Surface area of cell in square micrometerscell_volume[cellid]- Volume of cell in cubic micrometers
Functions for mapping between cell indices (not cell IDs) and various classification schemes. These are vectors indexed by sequential cell indices, often returning missing for cells without annotations:
ind2type[cellindex]- Map cell indices to primary type names (vector of strings)ind2category[cellindex]- Map cell indices to category (intrinsic/boundary/missing)ind2side[cellindex]- Map cell indices to hemisphere (left/right/missing)ind2superclass[cellindex],ind2class[cellindex],ind2subclass[cellindex]- Hierarchical classificationsind2nt[cellindex],type2nt(typename)- Map to neurotransmitter types
Specialized functions for creating complex spatial visualizations and analyzing spatial patterns in the hexagonal coordinate system:
eyetriad(cellid)- Generate eye-centered triad for specific celltypetriad(celltype)- Generate type-centered triad visualizationcelltriad(cellid)- Generate cell-centered triad visualizationeyehot(image; sat)- Convert array to heatmap using hot colormap with eye maskingellipsesummary(image),drawellipse(ellipse)- Ellipse fitting and visualizationhexproject,drawpqaxes,hexannulus- Hexagonal projection utilitiesHexagonEye(p, q, hexelsize)- Create hexagon at eye coordinates
Miscellaneous helper functions for data processing and analysis:
convert2arrows(matrix)- Convert connectivity matrix to arrow formatfindcenter(coordinates)- Find center of coordinate clusterconvcluster(data)- Convex clustering analysisseven- Utility constant/functionName- NamedArrays indexing utility
set_default_synapses(version)- Set default synapse version (Princeton/Buhmann)enable_both_synapses(enabled)- Enable simultaneous loading of both synapse versions
The repository contains complete analysis scripts that reproduce the figures from both Nature papers:
The PartsListPaper/ directory contains scripts for Matsliah, Yu, et al., Neuronal parts list and wiring diagram for a visual system, Nature 634:166-180 (2024).
cd PartsListPaper
julia --project=. "Fig 1 cell numbers.jl" # Reproduce Figure 1
julia --project=. "dendrograms.jl" # Hierarchical clusteringSee PartsListPaper/README.md for detailed usage instructions.
The FormVisionPaper/ directory contains scripts for Seung, Predicting visual function by interpreting a neuronal wiring diagram, Nature 634:113-123 (2024).
cd FormVisionPaper
julia --project=. FiguresSpatial.jl # Spatial analysis and montages
julia --project=. FiguresNonspatial.jl # Non-spatial connectivity analysisSee FormVisionPaper/README.md for Jupytext setup and detailed instructions.
All data is automatically downloaded via DataDeps.jl from the latest versions on the FlyWire Codex.
- Cell morphology and spatial coordinates
- Synaptic connectivity (Princeton and Buhmann predictions)
- Cell type annotations and hierarchical classifications
Data files are cached locally after first download (~350MB total).