NBLAST
NBLAST
NBLAST (Costa et al., 2016) is a method to quantify morphological similarity. It works on “dotprops” which represent neurons as tangent vectors. For each tangent vector in the query neuron, NBLAST finds the closest tangent vector in the target neuron and calculates a score from the distance between and the dotproduct of the two vectors. The final NBLAST score is the sum over all query-target vector pairs. Typically, this score is normalized to a self-self comparison (i.e. a perfect match would be 1).
VFB computes NBLAST scores for all (?) neurons in its database. So if all you want is a list of similar neurons, it’s fastest (and easiest) to get those directly from VFB.
# Import libs and initialise API objects
from vfb_connect.cross_server_tools import VfbConnect
import navis.interfaces.neuprint as neu
import pandas as pd
import navis
navis.set_pbars(jupyter=False)
vc = VfbConnect()
client = neu.Client('https://neuprint.janelia.org', dataset='hemibrain:v1.1')
First let’s write a little function to grab VFB neurons and turn them into navis
neurons. This is modified from vc.neo_query_wrapper.get_images
.
import requests
from tqdm import tqdm
def get_vfb_neurons(vfb_ids, template='JRC2018Unisex'):
"""Load neurons from VFB as navis.TreeNeurons."""
vfb_ids = list(navis.utils.make_iterable(vfb_ids))
inds = vc.neo_query_wrapper.get_anatomical_individual_TermInfo(short_forms=vfb_ids)
nl = []
# Note: queries should be parallelized in the future
# -> for pymaid I use request-futures which works really well
for i in tqdm(inds, desc='Loading VFB neurons', leave=False):
if not ('has_image' in i['term']['core']['types']):
continue
label = i['term']['core']['label']
image_matches = [x['image'] for x in i['channel_image']]
if not image_matches:
continue
for imv in image_matches:
if imv['template_anatomy']['label'] == template:
r = requests.get(imv['image_folder'] + '/volume.swc')
### Slightly dodgy warning - could mask network errors
if not r.ok:
warnings.warn("No '%s' file found for '%s'." % (image_type, label))
continue
# `id` should ideally be unique but that's not enforced
n = navis.TreeNeuron(r.text, name=label, id=i['term']['core']['short_form'])
# This registers attributes that you want to show in the summary
# alternatively we could have a generic attribute like so:
# n.template = template
n._register_attr("template", template, temporary=False)
# I assume all available templates are in microns?
# @Robbie -do we have this metadata on templates? If not, we should add ASAP.
n.units = '1 micron'
nl.append(n)
return navis.NeuronList(nl)
# Search for similar neurons using the VFB ID of an ellipsoid body neuron in FAFB
# We got that ID from a search on the VFB website
similar_to_EPG6L1 = vc.get_similar_neurons('VFB_001012ay')
similar_to_EPG6L1
id | NBLAST_score | label | types | source_id | accession_in_source | |
---|---|---|---|---|---|---|
0 | VFB_jrchjtk6 | 0.525 | EPG(PB08)_L6 - 541870397 | [EB-PB 1 glomerulus-D/Vgall neuron] | neuprint_JRC_Hemibrain_1point1 | 541870397 |
1 | VFB_jrchjtk8 | 0.524 | EPG(PB08)_L6 - 912601268 | [EB-PB 1 glomerulus-D/Vgall neuron] | neuprint_JRC_Hemibrain_1point1 | 912601268 |
2 | VFB_jrchjtkb | 0.504 | EPG(PB08)_L6 - 788794171 | [EB-PB 1 glomerulus-D/Vgall neuron] | neuprint_JRC_Hemibrain_1point1 | 788794171 |
3 | VFB_jrchjtji | 0.481 | EL(EQ5)_L - 1036753721 | [EBw.AMP.s-Dga-s.b neuron] | neuprint_JRC_Hemibrain_1point1 | 1036753721 |
# Read those neurons from VFB
query = get_vfb_neurons('VFB_001012ay')
matches = get_vfb_neurons(similar_to_EPG6L1.id.values)
matches
type | name | id | n_nodes | n_connectors | n_branches | n_leafs | cable_length | soma | units | template | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | navis.TreeNeuron | EPG(PB08)_L6 - 912601268 | VFB_jrchjtk8 | 9819 | None | 1000 | 1015 | 2211.292188 | None | 1 micron | JRC2018Unisex |
1 | navis.TreeNeuron | EL(EQ5)_L - 1036753721 | VFB_jrchjtji | 13864 | None | 1942 | 1974 | 3403.311508 | [1] | 1 micron | JRC2018Unisex |
2 | navis.TreeNeuron | EPG(PB08)_L6 - 788794171 | VFB_jrchjtkb | 9651 | None | 962 | 987 | 2125.364857 | None | 1 micron | JRC2018Unisex |
3 | navis.TreeNeuron | EPG(PB08)_L6 - 541870397 | VFB_jrchjtk6 | 11042 | None | 1099 | 1127 | 2432.101351 | [1] | 1 micron | JRC2018Unisex |
# Define colors such that query is black
import seaborn as sns
colors = ['k'] + sns.color_palette('muted', len(matches))
navis.plot3d([query, matches], color=colors)