SlideShare a Scribd company logo
1 of 63
Download to read offline
neuprintr
accessing
data from
the FlyEM
HemiBrain
project using
R
Using Connectome Data
What can we do with
hemibrain data? A partial
(~35%) connectome but
the largest to date, with
morphologies
21,662 ~full neurons
4,495 cut neurons
67,475 unassigned fragments
9.5M presynapses
64M postsynapses
~35% connectivity completion
What can we do with
hemibrain data? A partial
(~35%) connectome but
the largest to date, with
morphologies
We can interact with it via
neuPrint, a database and
analysis ecosystem for
connectomics with a web
interface and API access
Further, we can use the
natverse! Specifically, we
can use its package
neuprintr to access
neuPrint's API endpoints
https://neuprint.janelia.org/
You can do a lot of basic
analysis in neuPrint. It's
great if you want to have a
quick look at something
Tutorial videos are
available to get you up to
speed with the web
interface.
You now need to login. To
do so, make an account.
The project is open to all,
so it will not need to be
approved
You will need to choose a
@gmail address
And now you are in! To
access the neuPrint API
programmatically you will
need to use your token. Go
to account
And you will see this page.
You token will be a long
string of numbers, symbols
and letters. This token is
only an example
asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5zaGFrZWVsLmJhdGVzQGdtYWlsLmN
vbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIjoiaHR0cHM7Ly9saDQuZ29vZ2xldXNlcmNvbnRlbnQuY2
9tLy1QeFVrTFZtbHdmcy9BQUFBQUFBQUFBDD9BQUFBQUFBQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMn
V0QjJBcFJSZlBRL21vL3Bob3RvLapwZz9zej01MCIsImV4cCI6MTczMjc1MjU2HH0.jhh1nMDBPl5A1HYKcszXM51
8NZeAhZG9jKy3hzVOWEU
You can build custom
queries in the web browser
to find neurons and their
connectivity.
These queries send a
message to a Neo4j
database, asking ito return
the right data, using a
cypher.
By clicking the 'I' button
you can view the cypher
that has been sent to this
database..
By clicking the 'I' button
you can view the cypher
that has been sent to this
database.
https://neo4j.com/develop
er/cypher-query-language/
The neuPrint data model
MATCH (m:`hemibrain_Meta`) WITH m.superLevelRois AS rois MATCH (neuron :`hemibrain_Neuron`) WHERE
(neuron.`LH(R)`= true) AND (neuron.`AL(R)`= true) RETURN neuron.bodyId AS bodyid, neuron.instance AS
bodyname, neuron.type AS bodytype, neuron.status AS neuronStatus, neuron.roiInfo AS roiInfo, neuron.size
AS size, neuron.pre AS npre, neuron.post AS npost, rois ORDER BY neuron.bodyId
Now we know
neuPrint, let's look to
the natverse and its
package neuprintr
http://natverse.org/
The
natverse is
a suite of R
tools for
getting and
analysing
neuron
data. It can
be used to
look at
synaptic
neuron
data, and
can pull
from both
CATMAID
and neuPrint
The R
package
neuprintr
has been
developed
to interact
with
neuPrint. It
can use the
available
API
endpoints
and also
send custom
cyphers
In order to
use the
natverse,
you will
need the
latest
versions of R
and R
Studio.
Details on
prerequisites
and
detailed
installation
here:
http://natver
se.org/nat/a
rticles/Install
ation.html
Can interact
with other
languages.
For
example,
the python
library
navis works
similarly
(https://gith
ub.com/schl
egelp/navis)
Install the natverse and neuprintr
install.packages(c("usethis", "devtools"))
usethis::browse_github_pat()
usethis::edit_r_environ() # Optionally connect to your github account,
# in order to avoid API rate limits
# then paste your your personal access token to your Renviron file
# I.e. by adding adding the following line, followed by a blank line:
# GITHUB_PAT= your_personal_access_token_here
.rs.restartR()
devtools::install_github("natverse/natverse") # install all packages of
# the natverse with one line
library(natverse) # load all packages of the natverse
devtools::install_github("natverse/neuprintr") # or install/update just
# neuprintr
library(neuprintr)
Get to grips with the
natverse by
exploring our
tutorials
http://natverse.org/
https://github.com/natverse/nat.examples
Get to grips with
neuprintr with our
vignettes and
example
http://natverse.org/neuprintr/articles/hemib
rain_opns.html
https://github.com/natverse/nat.examples
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
It is a great idea to wrap your queries in a function. This will make
your code cleaner and more reusable. you should just be able to
edit this example without worrying about the details.
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
In order to make a query, you need to specify which neuPrint
server you want to talk to, and dataset. Usually you will not need to
do anything as this will be handled by a one time user setting to
specify their preferred server, dataset and authentication token.
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
Internally neuprint_fetch_custom, which will look after the dataset
argument, and then go on to call the low level neuprint_fetch,
which will ensure that the connection object is valid. It sends a
POST request to the neuPrint server, and gives us its response.
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
This function takes one or more bodyids as input and returns the
name of the neurons. Bodyids typically come in as either character
vector or numeric format. The internal function id2json() will look
after formatting them appropriately for the query
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
Many functions that operate on neurons will have an argument
(all_segments) controlling whether they operate only for larger
objects (Neuron) or also on fragments (Segment). Restricting
queries to Neuron can result in big speed-ups.
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
In this function, cypher is the actual query written in the
Cypher query language. As you can see this step uses the sprintf
function to interpolate variables into a string.
The anatomy of a neuprintr function
neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments =
FALSE, conn = NULL, ...) {
all_segments.json = ifelse(all_segments,"Segment", "Neuron")
cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`)
WHERE n.bodyId=bodyId RETURN n.instance AS name",
id2json(bodyids),
all_segments.json)
nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...)
d = unlist(lapply(nc$data,nullToNA))
names(d) = bodyids
d
}
The results that come back from neuprint_fetch_custom are
typically in a big list object. For simple results, you can just unlist this
to make a vector. A function nullToNA is first applied in order to
ensure that missing values come back as NA.
Let's now go through
an example that
looks at olfactory
projection neurons
http://natverse.org/neuprintr/articles/hemib
rain_opns.html
Connect to neuPrint via R
install.packages(c("usethis", "devtools"))
usethis::browse_github_pat()
usethis::edit_r_environ() # Optionally connect to your github account,
# in order to avoid API rate limits
# then paste your your personal access token to your Renviron file
# I.e. by adding adding the following line, followed by a blank line:
# GITHUB_PAT= your_personal_access_token_here
.rs.restartR()
devtools::install_github("natverse/natverse") # install all packages of
# the natverse with one line
library(natverse) # load all packages of the natverse
devtools::install_github("natverse/neuprintr") # or install/update just
# neuprintr
library(neuprintr)
Connect to neuPrint
## example explicitly specifying connection options
conn = neuprint_login(server= "neuprint.janelia.org", token=
"asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5za
GFrZWVsLmJhdGVzQGdtYWlsLmNvbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIj
oiaHR0cHM7Ly9saDQuZ35vZ2xldXNlcmNvbnRlbnQuY29tLy1QeFVrTFZtbHdmcy9BQUFBQUF
BQUFBDD9BQUFBQUFBQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMnV0QjJBcFJSZlBRL21v
L3Bob3RvLapwZz9zej01MCIsImV4cCI6MTczMjc1MjM2HH0.jhh1nMDBPl5A1HYKcszXM518NZ
eAhZG9jKy3hzVOWEU")# this is a non-functional example token
## examples assuming that neuprint_* environment variables/options are set
conn = neuprint_login()
Set up some defaults in your R environ
Usethis::edit_r_environ() # use this to edit your environment file directly
## Add these lines to your file:
neuprint_server = "https://neuprint.janelia.org"
neuprint_token =
"asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5zaGFrZWVsLmJhdG
VzQGdtYWlsLmNvbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIjoiaHR0cHM7Ly9saDQ
uZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1QeFVrTFZtbHdmcy9BQUFBQUFBQUFBDD9BQUFBQUF
BQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMnV0QjJBcFJSZlBRL21vL3Bob3RvLapwZz9zej0
1MCIsImV4cCI6MTczMjc1MjU2HH0.jhh1nMDBPl5A1HYKcszXM518NZeAhZG9jKy3hzVOWEU"
neuprint_dataset = "hemibrain:v1.0"
# Leave a space at the end of the file
# Restart R
.rs.restartR()
You may want to change your default
dataset in the future, for now hemibrain
Usethis::edit_r_environ() # use this to edit your environment file directly
## Add these lines to your file:
neuprint_server = "https://neuprint.janelia.org"
neuprint_token =
"asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5zaGFrZWVsLmJhdG
VzQGdtYWlsLmNvbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIjoiaHR0cHM7Ly9saDQ
uZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1QeFVrTFZtbHdmcy9BQUFBQUFBQUFBDD9BQUFBQUF
BQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMnV0QjJBcFJSZlBRL21vL3Bob3RvLapwZz9zej0
1MCIsImV4cCI6MTczMjc1MjU2HH0.jhh1nMDBPl5A1HYKcszXM518NZeAhZG9jKy3hzVOWEU"
neuprint_dataset = "hemibrain:v1.0"
# Leave a space at the end of the file
# Restart R
.rs.restartR()
Let's check you are logged in
## See whether this simple function works for you:
available.datasets = neuprint_datasets()
available.datasets
Great – now install some other packages
we will use in the following examples
# install
if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager")
if(!require('ComplexHeatmap')) BiocManager::install("ComplexHeatmap")
if(!require('ggnetwork')) install.packages("ggnetwork")
if(!require('network')) install.packages("network")
# load
library(natverse)
library(neuprintr)
library(dendroextras)
library(ComplexHeatmap)
library(ggnetwork)
library(network)
And let's not make ugly things. Let's set up
some nice colours
## some nice colors!! Inspired by LaCroixColoR
lacroix = c("#C70E7B", "#FC6882", "#007BC3", "#54BCD1", "#EF7C12", "#F4B95A",
"#009F3F", "#8FDA04", "#AF6125", "#F4E3C7", "#B25D91", "#EFC7E6",
"#EF7C12", "#F4B95A", "#C23A4B", "#FBBB48", "#EFEF46", "#31D64D",
"#132157","#EE4244", "#D72000", "#1BB6AF")
names(lacroix) = c("purple", "pink",
"blue", "cyan",
"darkorange", "paleorange",
"darkgreen", "green",
"brown", "palebrown",
"mauve", "lightpink",
"orange", "midorange",
"darkred", "darkyellow",
"yellow", "palegreen",
"navy","cerise",
"red", "marine")
Finding and
reading
neurons
Challenge:
Once you
complete
the next
section, try
to get this
image of all
hemibrain
mushroom
body output
neurons
(MBONs)
Get information on olfactory projection
neurons in the hemibrain data
### Let's find some in our HemiBrain data:
opn.info = neuprint_search(".*mPN1.*")
opn.info[!is.na(opn.info$type),"type"] = opn.info[!is.na(opn.info$type),"name"]
rownames(opn.info) = opn.info$bodyid
#### Add AL glomerulus information from the name
name.split = strsplit(opn.info$name,split=c("(|_"))
gloms = sapply(name.split, function(x) tryCatch(x[[2]], error = function(e) ""))
opn.info$glomerulus = gloms
opn.info = subset(opn.info, glomerulus!="")
#### so there seem to be
print(length(gloms))
#### OPNs and and
print(length(unique(gloms)))
#### OPNs with unique glomerulus innervations
View(opn.info)
Use the bodyIds we have found to read a
neuron skeleton from neuPrint
## Let's quickly read one neuron, and have a look at it!
opn = neuprint_read_neuron(opn.info$bodyid[1])
### visualise:
nopen3d()
plot3d(opn, WithConnectors = TRUE, col = lacroix[["brown"]], lwd = 2)
Use the bodyIds we have found to read
neuron skeletons from neuPrint
## Now that we have all of the bodyIds, we can read these neurons from neuPrint:
opns = neuprint_read_neurons(opn.info$bodyid)
nopen3d()
plot3d(opns, col = sample(lacroix,length(opns), replace = TRUE), lwd = 2)
What information can we fetch
separately?
### Why is this function so slow?
### Because it fetches fragmented neuron skeletons assigned to the same neuron
### Stitched them into one neuron, grabs all the neuron's synapses
### and tries to work out where the soma is. If you want to move faster
### You can grab bits separately and quickly:
?neuprint_read_neuron_simple
?neuprint_get_synapses
?neuprint_assign_connectors
?neuprint_locate_soma
?neuprint_get_neuron_names
?neuprint_get_meta
### Try:
neuprint_get_meta(c(818983130, 1796818119))
Fetch bodyIds by brain region
### The regions of interest available are:
rois = sort(neuprint_ROIs())
rois
## We don't we try fetching all of the neurons in a glomerulus of the antennal lobe?
ca.info = neuprint_find_neurons(
input_ROIs = "CA(R)",
output_ROIs = NULL,
all_segments = FALSE # if true, fragments smaller than 'neurons' are returned as well
)
## So how many neurons is that?
print(nrow(ca.info))
## A lot! But what about that pesky load of Kenyon cells
ca.info = subset(ca.info, !is.na(bodyname) & neuronStatus == "Traced")
ca.info = ca.info[!grepl("KC",ca.info$bodyname),]
## So how many neurons is that?
print(nrow(ca.info))
Getting
neuropil
volumes
Challenge:
Once you
complete
the next
section, try
to get this
image of
the
mushroom
body
Let's get an mesh3d object for the
antennal lobe (AL)
## Let's get some neuropil volume data from neuPrint!
### First, we gotta see what is available:
rois
# Read in the AL mesh!
al.mesh = neuprint_ROI_mesh(roi = "AL(R)")
nopen3d()# set view
plot3d(al.mesh, add = TRUE, alpha = 0.1, col = lacroix[["orange"]])
Let's get an mesh3d object for the main
olfactory neuropils
# And get the other main olfactory neuropils
ca.mesh = neuprint_ROI_mesh(roi = "CA(R)")
lh.mesh = neuprint_ROI_mesh(roi = "LH(R)")
malt.mesh = neuprint_ROI_mesh(roi = "mALT(R)")
plot3d(ca.mesh, add = TRUE, alpha = 0.3, col = lacroix[["pink"]])
plot3d(lh.mesh, add = TRUE, alpha = 0.3, col = lacroix[["green"]])
plot3d(malt.mesh, add = TRUE, alpha = 0.9, col = "grey30")
# save images as .png
rgl.snapshot(filename = "images/hemibrain_olfactory_neuropils.png", fmt ="png")
Plot meshes and neurons together
# And get the other main olfactory neuropils
nopen3d()
plot3d(al.mesh, add = TRUE, alpha = 0.5, col = "grey")
plot3d(ca.mesh, add = TRUE, alpha = 0.5, col = "grey")
plot3d(lh.mesh, add = TRUE, alpha = 0.5, col = "grey")
plot3d(opns, col = sample(lacroix,length(opns), replace = TRUE), lwd = 2)
Getting
neuron
connectivity
Challenge:
Once you
complete
the next
section, try
to get this
image of
MBON inputs
onto the
DAN PPL104
(PPL1a'3)
And now the really exciting bit! How do
these neurons connect to each other?
## We are looking at connectivity between OPNs.
### We can get an adjaceny matrix between all of these OPNs
opn.adj = neuprint_get_adjacency_matrix(bodyids = opn.info$bodyid)
rownames(opn.adj.comp) = colnames(opn.adj.comp) = opn.info$glomerulus
opn.adj.comp = t(apply(t(opn.adj.comp), 2, function(x) tapply(x,
colnames(opn.adj.comp), sum, na.rm = TRUE)))
opn.adj.comp = apply(opn.adj.comp, 2, function(x) tapply(x, rownames(opn.adj.comp),
sum, na.rm = TRUE))
Heatmap(opn.adj.comp, col = my_palette)
And now the really exciting bit! How do
these neurons connect to each other?
Other ways to look at connectivity
## What about OPN connectivity to neurons not in this set of OPNs?
### First, is there a common partner to all OPNs?
common = neuprint_common_connectivity(opn.info$bodyid, prepost = "PRE")
### could use 'post' for downstream
dim(common)
### What about the food hub PNs?
### The glomerulus DM1 is interesting, because it is involved in an axo-axonic
### 'food odour' related community in the lateral horn (Bates & Schlegel et al. 2020)
DM1.opn.info = subset(opn.info, grepl("DM1|DM3|DM4|VM3|VA4",name))
DM1.common = neuprint_common_connectivity(DM1.opn.info$bodyid, prepost = "PRE")
dim(DM1.common)
DM1.common.meta = neuprint_get_meta(colnames(DM1.common)) # what are they?
View(DM1.common.meta) # Huhh, local neurons, the APL and some LH stuff
Other ways to look at connectivity
## We can also get all of the neurons in the database that connect to the
### query neurons, either upstream or downstream of them
DM1.opn.connected = neuprint_connection_table(DM1.opn.info$bodyid, prepost = "POST")
### In which brain region are these partners?
table(DM1.opn.connected$roi)
Other ways to look at connectivity
## Let's have a look at what the strongest downstream partners look like
DM1.opn.connected.strong = subset(DM1.opn.connected,weight>100, prepost = "POST")
DM1.targets = neuprint_read_neurons(DM1.opn.connected.strong$partner)
nopen3d()
plot3d(DM1.targets, lwd = 2, col = sample(lacroix,length(DM1.targets),replace=TRUE))
View(DM1.targets[,])
Other ways to look at connectivity
## So there are three lateral horn neuron targets of the axon there
### c("359214479", "359891881", "511616870"), found using nat::find.neuron
### Let's move forward with those
lhns = c(359214479, 359891881, 511616870)
lhn.cols = c(lacroix[["marine"]],lacroix[["blue"]],lacroix[["green"]])
names(lhn.cols) = DM1.targets[lhns,"type"]
lh.targets = DM1.targets[lhns]
clear3d()
plot3d(lh.targets, lwd = 2, col = c(lacroix[["marine"]],
lacroix[["blue"]],
lacroix[["green"]]))
plot3d(subset(opns,grepl("DM1",name)),lwd=2,col=lacroix[["orange"]])
Let's make a network graph to see how
different OPNs can reach these LHNs
### Which other OPNs impinge on it?, vwhatever path?
shortest.paths = data.frame()
for(lhn in lhns){
for(b in opn.info$bodyid){ # PN -> LHN only
sp = neuprint_get_shortest_paths(body_pre = b, body_post = lhn, weightT = 10)
dupe = ifelse( is.na(which(duplicated(sp$to))[1]),nrow(sp),which(duplicated(sp$to))[1])
shortest = sp[1:dupe,]
if(nrow(shortest)>0 & nrow(shortest)<5 ){
shortest$order.to = paste(1:nrow(shortest), nrow(shortest), sep = "/")
shortest$order.from = paste(1:nrow(shortest)-1, nrow(shortest), sep = "/")
shortest[1,"order.from"] = opn.info[as.character(b),"glomerulus"]
shortest[nrow(shortest),"order.to"] = DM1.targets[lhn,"type"]
shortest.paths = rbind(shortest.paths, shortest)
}
}
}
Let's make a network graph to see how
different OPNs can reach these LHNs
paths = aggregate(list(weight = shortest.paths$weight), list(order.from =
shortest.paths$order.from, order.to = shortest.paths$order.to), sum)
n = network(paths, matrix.type = "edgelist", ignore.eval = FALSE, layout =
"fruchtermanreingold", names.eval = "weight", directed = TRUE)
n = ggnetwork(n, cell.jitter = 0.75, arrow.gap = 0.01)
# Set colours
orders = unique(c(paths$order.to,paths$order.from))
order.cols = rep("grey30",length(orders))
names(order.cols) = orders
gloms = unique(opn.info$glomerulus)
opn.cols = rep(lacroix[["orange"]],length(gloms))
names(opn.cols) = gloms
opn.cols =
c(opn.cols,lhn.cols,order.cols[!names(order.cols)%in%c(names(lhn.cols),names(opn.cols))])
Let's make a network graph to see how
different OPNs can reach these LHNs
# Plot
ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_edges(aes(color = vertex.names),
curvature = 0.05,
arrow = arrow(length = unit(6, "pt"),
type = "closed")) +
geom_nodes(aes(color = vertex.names, size = 6)) +
geom_edgetext(aes(label = weight, color = vertex.names), fill = NA) +
geom_nodelabel_repel(aes(color = vertex.names, label = vertex.names),
fontface = "bold", box.padding = unit(1, "lines")) +
scale_color_manual(values = opn.cols) +
scale_fill_manual(values = opn.cols) +
theme_blank() +
guides(color = FALSE, shape = FALSE, fill = FALSE, size = FALSE, linetype = FALSE) + ylab("") +
xlab("")
Let's make a network graph to see how
different OPNs can reach these LHNs
That's it for now! If something is
broken or you want to suggest
a new feature, contact us
preferably by making an issue
on GitHub
https://github.com/natverse/neuprintr/issues
@as_bates
alexanderbates
@gsxej
jefferis
@RFranconville
romainFr
@uni_matrix
schlegelp
@janeliaflyem
connectome-neuprint
neuprint
hemibrain

More Related Content

Similar to Accessing hemibrain data using Neuprintr

Comparing EDA with classical and Bayesian analysis.pptx
Comparing EDA with classical and Bayesian analysis.pptxComparing EDA with classical and Bayesian analysis.pptx
Comparing EDA with classical and Bayesian analysis.pptx
PremaGanesh1
 
NeuralProcessingofGeneralPurposeApproximatePrograms
NeuralProcessingofGeneralPurposeApproximateProgramsNeuralProcessingofGeneralPurposeApproximatePrograms
NeuralProcessingofGeneralPurposeApproximatePrograms
Mohid Nabil
 
Data Manipulation with Numpy and Pandas in PythonStarting with N
Data Manipulation with Numpy and Pandas in PythonStarting with NData Manipulation with Numpy and Pandas in PythonStarting with N
Data Manipulation with Numpy and Pandas in PythonStarting with N
OllieShoresna
 

Similar to Accessing hemibrain data using Neuprintr (20)

cluster(python)
cluster(python)cluster(python)
cluster(python)
 
Cheat sheets for AI
Cheat sheets for AICheat sheets for AI
Cheat sheets for AI
 
The steps of R code Master.pptx
The steps of R code Master.pptxThe steps of R code Master.pptx
The steps of R code Master.pptx
 
Feed forward neural network for sine
Feed forward neural network for sineFeed forward neural network for sine
Feed forward neural network for sine
 
Neural network in R by Aman Chauhan
Neural network in R by Aman ChauhanNeural network in R by Aman Chauhan
Neural network in R by Aman Chauhan
 
Comparing EDA with classical and Bayesian analysis.pptx
Comparing EDA with classical and Bayesian analysis.pptxComparing EDA with classical and Bayesian analysis.pptx
Comparing EDA with classical and Bayesian analysis.pptx
 
Deep Learning with Apache MXNet (September 2017)
Deep Learning with Apache MXNet (September 2017)Deep Learning with Apache MXNet (September 2017)
Deep Learning with Apache MXNet (September 2017)
 
NeuralProcessingofGeneralPurposeApproximatePrograms
NeuralProcessingofGeneralPurposeApproximateProgramsNeuralProcessingofGeneralPurposeApproximatePrograms
NeuralProcessingofGeneralPurposeApproximatePrograms
 
Towards neuralprocessingofgeneralpurposeapproximateprograms
Towards neuralprocessingofgeneralpurposeapproximateprogramsTowards neuralprocessingofgeneralpurposeapproximateprograms
Towards neuralprocessingofgeneralpurposeapproximateprograms
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data Visualisation
 
Data Manipulation with Numpy and Pandas in PythonStarting with N
Data Manipulation with Numpy and Pandas in PythonStarting with NData Manipulation with Numpy and Pandas in PythonStarting with N
Data Manipulation with Numpy and Pandas in PythonStarting with N
 
User biglm
User biglmUser biglm
User biglm
 
Introduction to Tensor Flow for Optical Character Recognition (OCR)
Introduction to Tensor Flow for Optical Character Recognition (OCR)Introduction to Tensor Flow for Optical Character Recognition (OCR)
Introduction to Tensor Flow for Optical Character Recognition (OCR)
 
Decision Tree.pptx
Decision Tree.pptxDecision Tree.pptx
Decision Tree.pptx
 
Neural Networks
Neural NetworksNeural Networks
Neural Networks
 
ML with python.pdf
ML with python.pdfML with python.pdf
ML with python.pdf
 
Deep learning approach for intelligent intrusion detection system
Deep learning approach for intelligent intrusion detection systemDeep learning approach for intelligent intrusion detection system
Deep learning approach for intelligent intrusion detection system
 
Snakes for Camels
Snakes for CamelsSnakes for Camels
Snakes for Camels
 
Lecture 7: Recurrent Neural Networks
Lecture 7: Recurrent Neural NetworksLecture 7: Recurrent Neural Networks
Lecture 7: Recurrent Neural Networks
 
Classification of Iris Data using Kernel Radial Basis Probabilistic Neural N...
Classification of Iris Data using Kernel Radial Basis Probabilistic  Neural N...Classification of Iris Data using Kernel Radial Basis Probabilistic  Neural N...
Classification of Iris Data using Kernel Radial Basis Probabilistic Neural N...
 

Recently uploaded

Module for Grade 9 for Asynchronous/Distance learning
Module for Grade 9 for Asynchronous/Distance learningModule for Grade 9 for Asynchronous/Distance learning
Module for Grade 9 for Asynchronous/Distance learning
levieagacer
 
Digital Dentistry.Digital Dentistryvv.pptx
Digital Dentistry.Digital Dentistryvv.pptxDigital Dentistry.Digital Dentistryvv.pptx
Digital Dentistry.Digital Dentistryvv.pptx
MohamedFarag457087
 
Biogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune Waterworlds
Biogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune WaterworldsBiogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune Waterworlds
Biogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune Waterworlds
Sérgio Sacani
 
Pests of cotton_Sucking_Pests_Dr.UPR.pdf
Pests of cotton_Sucking_Pests_Dr.UPR.pdfPests of cotton_Sucking_Pests_Dr.UPR.pdf
Pests of cotton_Sucking_Pests_Dr.UPR.pdf
PirithiRaju
 
development of diagnostic enzyme assay to detect leuser virus
development of diagnostic enzyme assay to detect leuser virusdevelopment of diagnostic enzyme assay to detect leuser virus
development of diagnostic enzyme assay to detect leuser virus
NazaninKarimi6
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
The Mariana Trench remarkable geological features on Earth.pptx
The Mariana Trench remarkable geological features on Earth.pptxThe Mariana Trench remarkable geological features on Earth.pptx
The Mariana Trench remarkable geological features on Earth.pptx
seri bangash
 

Recently uploaded (20)

Module for Grade 9 for Asynchronous/Distance learning
Module for Grade 9 for Asynchronous/Distance learningModule for Grade 9 for Asynchronous/Distance learning
Module for Grade 9 for Asynchronous/Distance learning
 
Digital Dentistry.Digital Dentistryvv.pptx
Digital Dentistry.Digital Dentistryvv.pptxDigital Dentistry.Digital Dentistryvv.pptx
Digital Dentistry.Digital Dentistryvv.pptx
 
GBSN - Biochemistry (Unit 1)
GBSN - Biochemistry (Unit 1)GBSN - Biochemistry (Unit 1)
GBSN - Biochemistry (Unit 1)
 
SAMASTIPUR CALL GIRL 7857803690 LOW PRICE ESCORT SERVICE
SAMASTIPUR CALL GIRL 7857803690  LOW PRICE  ESCORT SERVICESAMASTIPUR CALL GIRL 7857803690  LOW PRICE  ESCORT SERVICE
SAMASTIPUR CALL GIRL 7857803690 LOW PRICE ESCORT SERVICE
 
Biogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune Waterworlds
Biogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune WaterworldsBiogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune Waterworlds
Biogenic Sulfur Gases as Biosignatures on Temperate Sub-Neptune Waterworlds
 
Introduction to Viruses
Introduction to VirusesIntroduction to Viruses
Introduction to Viruses
 
GBSN - Microbiology (Unit 3)
GBSN - Microbiology (Unit 3)GBSN - Microbiology (Unit 3)
GBSN - Microbiology (Unit 3)
 
Pests of cotton_Sucking_Pests_Dr.UPR.pdf
Pests of cotton_Sucking_Pests_Dr.UPR.pdfPests of cotton_Sucking_Pests_Dr.UPR.pdf
Pests of cotton_Sucking_Pests_Dr.UPR.pdf
 
chemical bonding Essentials of Physical Chemistry2.pdf
chemical bonding Essentials of Physical Chemistry2.pdfchemical bonding Essentials of Physical Chemistry2.pdf
chemical bonding Essentials of Physical Chemistry2.pdf
 
9999266834 Call Girls In Noida Sector 22 (Delhi) Call Girl Service
9999266834 Call Girls In Noida Sector 22 (Delhi) Call Girl Service9999266834 Call Girls In Noida Sector 22 (Delhi) Call Girl Service
9999266834 Call Girls In Noida Sector 22 (Delhi) Call Girl Service
 
COST ESTIMATION FOR A RESEARCH PROJECT.pptx
COST ESTIMATION FOR A RESEARCH PROJECT.pptxCOST ESTIMATION FOR A RESEARCH PROJECT.pptx
COST ESTIMATION FOR A RESEARCH PROJECT.pptx
 
9654467111 Call Girls In Raj Nagar Delhi Short 1500 Night 6000
9654467111 Call Girls In Raj Nagar Delhi Short 1500 Night 60009654467111 Call Girls In Raj Nagar Delhi Short 1500 Night 6000
9654467111 Call Girls In Raj Nagar Delhi Short 1500 Night 6000
 
development of diagnostic enzyme assay to detect leuser virus
development of diagnostic enzyme assay to detect leuser virusdevelopment of diagnostic enzyme assay to detect leuser virus
development of diagnostic enzyme assay to detect leuser virus
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
pumpkin fruit fly, water melon fruit fly, cucumber fruit fly
pumpkin fruit fly, water melon fruit fly, cucumber fruit flypumpkin fruit fly, water melon fruit fly, cucumber fruit fly
pumpkin fruit fly, water melon fruit fly, cucumber fruit fly
 
FAIRSpectra - Enabling the FAIRification of Analytical Science
FAIRSpectra - Enabling the FAIRification of Analytical ScienceFAIRSpectra - Enabling the FAIRification of Analytical Science
FAIRSpectra - Enabling the FAIRification of Analytical Science
 
The Mariana Trench remarkable geological features on Earth.pptx
The Mariana Trench remarkable geological features on Earth.pptxThe Mariana Trench remarkable geological features on Earth.pptx
The Mariana Trench remarkable geological features on Earth.pptx
 
Zoology 5th semester notes( Sumit_yadav).pdf
Zoology 5th semester notes( Sumit_yadav).pdfZoology 5th semester notes( Sumit_yadav).pdf
Zoology 5th semester notes( Sumit_yadav).pdf
 
High Profile 🔝 8250077686 📞 Call Girls Service in GTB Nagar🍑
High Profile 🔝 8250077686 📞 Call Girls Service in GTB Nagar🍑High Profile 🔝 8250077686 📞 Call Girls Service in GTB Nagar🍑
High Profile 🔝 8250077686 📞 Call Girls Service in GTB Nagar🍑
 
300003-World Science Day For Peace And Development.pptx
300003-World Science Day For Peace And Development.pptx300003-World Science Day For Peace And Development.pptx
300003-World Science Day For Peace And Development.pptx
 

Accessing hemibrain data using Neuprintr

  • 2. What can we do with hemibrain data? A partial (~35%) connectome but the largest to date, with morphologies 21,662 ~full neurons 4,495 cut neurons 67,475 unassigned fragments 9.5M presynapses 64M postsynapses ~35% connectivity completion
  • 3. What can we do with hemibrain data? A partial (~35%) connectome but the largest to date, with morphologies
  • 4. We can interact with it via neuPrint, a database and analysis ecosystem for connectomics with a web interface and API access
  • 5. Further, we can use the natverse! Specifically, we can use its package neuprintr to access neuPrint's API endpoints
  • 7. You can do a lot of basic analysis in neuPrint. It's great if you want to have a quick look at something
  • 8. Tutorial videos are available to get you up to speed with the web interface.
  • 9. You now need to login. To do so, make an account. The project is open to all, so it will not need to be approved
  • 10. You will need to choose a @gmail address
  • 11. And now you are in! To access the neuPrint API programmatically you will need to use your token. Go to account
  • 12. And you will see this page. You token will be a long string of numbers, symbols and letters. This token is only an example asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5zaGFrZWVsLmJhdGVzQGdtYWlsLmN vbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIjoiaHR0cHM7Ly9saDQuZ29vZ2xldXNlcmNvbnRlbnQuY2 9tLy1QeFVrTFZtbHdmcy9BQUFBQUFBQUFBDD9BQUFBQUFBQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMn V0QjJBcFJSZlBRL21vL3Bob3RvLapwZz9zej01MCIsImV4cCI6MTczMjc1MjU2HH0.jhh1nMDBPl5A1HYKcszXM51 8NZeAhZG9jKy3hzVOWEU
  • 13. You can build custom queries in the web browser to find neurons and their connectivity.
  • 14. These queries send a message to a Neo4j database, asking ito return the right data, using a cypher.
  • 15. By clicking the 'I' button you can view the cypher that has been sent to this database..
  • 16. By clicking the 'I' button you can view the cypher that has been sent to this database. https://neo4j.com/develop er/cypher-query-language/
  • 18. MATCH (m:`hemibrain_Meta`) WITH m.superLevelRois AS rois MATCH (neuron :`hemibrain_Neuron`) WHERE (neuron.`LH(R)`= true) AND (neuron.`AL(R)`= true) RETURN neuron.bodyId AS bodyid, neuron.instance AS bodyname, neuron.type AS bodytype, neuron.status AS neuronStatus, neuron.roiInfo AS roiInfo, neuron.size AS size, neuron.pre AS npre, neuron.post AS npost, rois ORDER BY neuron.bodyId
  • 19. Now we know neuPrint, let's look to the natverse and its package neuprintr http://natverse.org/
  • 20. The natverse is a suite of R tools for getting and analysing neuron data. It can be used to look at synaptic neuron data, and can pull from both CATMAID and neuPrint The R package neuprintr has been developed to interact with neuPrint. It can use the available API endpoints and also send custom cyphers
  • 21. In order to use the natverse, you will need the latest versions of R and R Studio. Details on prerequisites and detailed installation here: http://natver se.org/nat/a rticles/Install ation.html Can interact with other languages. For example, the python library navis works similarly (https://gith ub.com/schl egelp/navis)
  • 22. Install the natverse and neuprintr install.packages(c("usethis", "devtools")) usethis::browse_github_pat() usethis::edit_r_environ() # Optionally connect to your github account, # in order to avoid API rate limits # then paste your your personal access token to your Renviron file # I.e. by adding adding the following line, followed by a blank line: # GITHUB_PAT= your_personal_access_token_here .rs.restartR() devtools::install_github("natverse/natverse") # install all packages of # the natverse with one line library(natverse) # load all packages of the natverse devtools::install_github("natverse/neuprintr") # or install/update just # neuprintr library(neuprintr)
  • 23. Get to grips with the natverse by exploring our tutorials http://natverse.org/ https://github.com/natverse/nat.examples
  • 24. Get to grips with neuprintr with our vignettes and example http://natverse.org/neuprintr/articles/hemib rain_opns.html https://github.com/natverse/nat.examples
  • 25. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } It is a great idea to wrap your queries in a function. This will make your code cleaner and more reusable. you should just be able to edit this example without worrying about the details.
  • 26. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } In order to make a query, you need to specify which neuPrint server you want to talk to, and dataset. Usually you will not need to do anything as this will be handled by a one time user setting to specify their preferred server, dataset and authentication token.
  • 27. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } Internally neuprint_fetch_custom, which will look after the dataset argument, and then go on to call the low level neuprint_fetch, which will ensure that the connection object is valid. It sends a POST request to the neuPrint server, and gives us its response.
  • 28. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } This function takes one or more bodyids as input and returns the name of the neurons. Bodyids typically come in as either character vector or numeric format. The internal function id2json() will look after formatting them appropriately for the query
  • 29. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } Many functions that operate on neurons will have an argument (all_segments) controlling whether they operate only for larger objects (Neuron) or also on fragments (Segment). Restricting queries to Neuron can result in big speed-ups.
  • 30. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } In this function, cypher is the actual query written in the Cypher query language. As you can see this step uses the sprintf function to interpolate variables into a string.
  • 31. The anatomy of a neuprintr function neuprint_get_neuron_names <- function(bodyids, dataset = NULL, all_segments = FALSE, conn = NULL, ...) { all_segments.json = ifelse(all_segments,"Segment", "Neuron") cypher = sprintf("WITH %s AS bodyIds UNWIND bodyIds AS bodyId MATCH (n:`%s`) WHERE n.bodyId=bodyId RETURN n.instance AS name", id2json(bodyids), all_segments.json) nc = neuprint_fetch_custom(cypher=cypher, conn = conn, dataset = dataset, ...) d = unlist(lapply(nc$data,nullToNA)) names(d) = bodyids d } The results that come back from neuprint_fetch_custom are typically in a big list object. For simple results, you can just unlist this to make a vector. A function nullToNA is first applied in order to ensure that missing values come back as NA.
  • 32. Let's now go through an example that looks at olfactory projection neurons http://natverse.org/neuprintr/articles/hemib rain_opns.html
  • 33. Connect to neuPrint via R install.packages(c("usethis", "devtools")) usethis::browse_github_pat() usethis::edit_r_environ() # Optionally connect to your github account, # in order to avoid API rate limits # then paste your your personal access token to your Renviron file # I.e. by adding adding the following line, followed by a blank line: # GITHUB_PAT= your_personal_access_token_here .rs.restartR() devtools::install_github("natverse/natverse") # install all packages of # the natverse with one line library(natverse) # load all packages of the natverse devtools::install_github("natverse/neuprintr") # or install/update just # neuprintr library(neuprintr)
  • 34. Connect to neuPrint ## example explicitly specifying connection options conn = neuprint_login(server= "neuprint.janelia.org", token= "asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5za GFrZWVsLmJhdGVzQGdtYWlsLmNvbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIj oiaHR0cHM7Ly9saDQuZ35vZ2xldXNlcmNvbnRlbnQuY29tLy1QeFVrTFZtbHdmcy9BQUFBQUF BQUFBDD9BQUFBQUFBQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMnV0QjJBcFJSZlBRL21v L3Bob3RvLapwZz9zej01MCIsImV4cCI6MTczMjc1MjM2HH0.jhh1nMDBPl5A1HYKcszXM518NZ eAhZG9jKy3hzVOWEU")# this is a non-functional example token ## examples assuming that neuprint_* environment variables/options are set conn = neuprint_login()
  • 35. Set up some defaults in your R environ Usethis::edit_r_environ() # use this to edit your environment file directly ## Add these lines to your file: neuprint_server = "https://neuprint.janelia.org" neuprint_token = "asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5zaGFrZWVsLmJhdG VzQGdtYWlsLmNvbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIjoiaHR0cHM7Ly9saDQ uZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1QeFVrTFZtbHdmcy9BQUFBQUFBQUFBDD9BQUFBQUF BQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMnV0QjJBcFJSZlBRL21vL3Bob3RvLapwZz9zej0 1MCIsImV4cCI6MTczMjc1MjU2HH0.jhh1nMDBPl5A1HYKcszXM518NZeAhZG9jKy3hzVOWEU" neuprint_dataset = "hemibrain:v1.0" # Leave a space at the end of the file # Restart R .rs.restartR()
  • 36. You may want to change your default dataset in the future, for now hemibrain Usethis::edit_r_environ() # use this to edit your environment file directly ## Add these lines to your file: neuprint_server = "https://neuprint.janelia.org" neuprint_token = "asBatEsiOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFsZXhhbmRlci5zaGFrZWVsLmJhdG VzQGdtYWlsLmNvbSIsImxldmVsIjoicmVhZHdyaXRlIiwiaW1hZ2UtdXJsIjoiaHR0cHM7Ly9saDQ uZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1QeFVrTFZtbHdmcy9BQUFBQUFBQUFBDD9BQUFBQUF BQUFBQS9BQ0hpM3JleFZMeEI4Nl9FT1asb0dyMnV0QjJBcFJSZlBRL21vL3Bob3RvLapwZz9zej0 1MCIsImV4cCI6MTczMjc1MjU2HH0.jhh1nMDBPl5A1HYKcszXM518NZeAhZG9jKy3hzVOWEU" neuprint_dataset = "hemibrain:v1.0" # Leave a space at the end of the file # Restart R .rs.restartR()
  • 37. Let's check you are logged in ## See whether this simple function works for you: available.datasets = neuprint_datasets() available.datasets
  • 38. Great – now install some other packages we will use in the following examples # install if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager") if(!require('ComplexHeatmap')) BiocManager::install("ComplexHeatmap") if(!require('ggnetwork')) install.packages("ggnetwork") if(!require('network')) install.packages("network") # load library(natverse) library(neuprintr) library(dendroextras) library(ComplexHeatmap) library(ggnetwork) library(network)
  • 39. And let's not make ugly things. Let's set up some nice colours ## some nice colors!! Inspired by LaCroixColoR lacroix = c("#C70E7B", "#FC6882", "#007BC3", "#54BCD1", "#EF7C12", "#F4B95A", "#009F3F", "#8FDA04", "#AF6125", "#F4E3C7", "#B25D91", "#EFC7E6", "#EF7C12", "#F4B95A", "#C23A4B", "#FBBB48", "#EFEF46", "#31D64D", "#132157","#EE4244", "#D72000", "#1BB6AF") names(lacroix) = c("purple", "pink", "blue", "cyan", "darkorange", "paleorange", "darkgreen", "green", "brown", "palebrown", "mauve", "lightpink", "orange", "midorange", "darkred", "darkyellow", "yellow", "palegreen", "navy","cerise", "red", "marine")
  • 40. Finding and reading neurons Challenge: Once you complete the next section, try to get this image of all hemibrain mushroom body output neurons (MBONs)
  • 41. Get information on olfactory projection neurons in the hemibrain data ### Let's find some in our HemiBrain data: opn.info = neuprint_search(".*mPN1.*") opn.info[!is.na(opn.info$type),"type"] = opn.info[!is.na(opn.info$type),"name"] rownames(opn.info) = opn.info$bodyid #### Add AL glomerulus information from the name name.split = strsplit(opn.info$name,split=c("(|_")) gloms = sapply(name.split, function(x) tryCatch(x[[2]], error = function(e) "")) opn.info$glomerulus = gloms opn.info = subset(opn.info, glomerulus!="") #### so there seem to be print(length(gloms)) #### OPNs and and print(length(unique(gloms))) #### OPNs with unique glomerulus innervations View(opn.info)
  • 42. Use the bodyIds we have found to read a neuron skeleton from neuPrint ## Let's quickly read one neuron, and have a look at it! opn = neuprint_read_neuron(opn.info$bodyid[1]) ### visualise: nopen3d() plot3d(opn, WithConnectors = TRUE, col = lacroix[["brown"]], lwd = 2)
  • 43. Use the bodyIds we have found to read neuron skeletons from neuPrint ## Now that we have all of the bodyIds, we can read these neurons from neuPrint: opns = neuprint_read_neurons(opn.info$bodyid) nopen3d() plot3d(opns, col = sample(lacroix,length(opns), replace = TRUE), lwd = 2)
  • 44. What information can we fetch separately? ### Why is this function so slow? ### Because it fetches fragmented neuron skeletons assigned to the same neuron ### Stitched them into one neuron, grabs all the neuron's synapses ### and tries to work out where the soma is. If you want to move faster ### You can grab bits separately and quickly: ?neuprint_read_neuron_simple ?neuprint_get_synapses ?neuprint_assign_connectors ?neuprint_locate_soma ?neuprint_get_neuron_names ?neuprint_get_meta ### Try: neuprint_get_meta(c(818983130, 1796818119))
  • 45. Fetch bodyIds by brain region ### The regions of interest available are: rois = sort(neuprint_ROIs()) rois ## We don't we try fetching all of the neurons in a glomerulus of the antennal lobe? ca.info = neuprint_find_neurons( input_ROIs = "CA(R)", output_ROIs = NULL, all_segments = FALSE # if true, fragments smaller than 'neurons' are returned as well ) ## So how many neurons is that? print(nrow(ca.info)) ## A lot! But what about that pesky load of Kenyon cells ca.info = subset(ca.info, !is.na(bodyname) & neuronStatus == "Traced") ca.info = ca.info[!grepl("KC",ca.info$bodyname),] ## So how many neurons is that? print(nrow(ca.info))
  • 47. Let's get an mesh3d object for the antennal lobe (AL) ## Let's get some neuropil volume data from neuPrint! ### First, we gotta see what is available: rois # Read in the AL mesh! al.mesh = neuprint_ROI_mesh(roi = "AL(R)") nopen3d()# set view plot3d(al.mesh, add = TRUE, alpha = 0.1, col = lacroix[["orange"]])
  • 48. Let's get an mesh3d object for the main olfactory neuropils # And get the other main olfactory neuropils ca.mesh = neuprint_ROI_mesh(roi = "CA(R)") lh.mesh = neuprint_ROI_mesh(roi = "LH(R)") malt.mesh = neuprint_ROI_mesh(roi = "mALT(R)") plot3d(ca.mesh, add = TRUE, alpha = 0.3, col = lacroix[["pink"]]) plot3d(lh.mesh, add = TRUE, alpha = 0.3, col = lacroix[["green"]]) plot3d(malt.mesh, add = TRUE, alpha = 0.9, col = "grey30") # save images as .png rgl.snapshot(filename = "images/hemibrain_olfactory_neuropils.png", fmt ="png")
  • 49.
  • 50. Plot meshes and neurons together # And get the other main olfactory neuropils nopen3d() plot3d(al.mesh, add = TRUE, alpha = 0.5, col = "grey") plot3d(ca.mesh, add = TRUE, alpha = 0.5, col = "grey") plot3d(lh.mesh, add = TRUE, alpha = 0.5, col = "grey") plot3d(opns, col = sample(lacroix,length(opns), replace = TRUE), lwd = 2)
  • 51. Getting neuron connectivity Challenge: Once you complete the next section, try to get this image of MBON inputs onto the DAN PPL104 (PPL1a'3)
  • 52. And now the really exciting bit! How do these neurons connect to each other? ## We are looking at connectivity between OPNs. ### We can get an adjaceny matrix between all of these OPNs opn.adj = neuprint_get_adjacency_matrix(bodyids = opn.info$bodyid) rownames(opn.adj.comp) = colnames(opn.adj.comp) = opn.info$glomerulus opn.adj.comp = t(apply(t(opn.adj.comp), 2, function(x) tapply(x, colnames(opn.adj.comp), sum, na.rm = TRUE))) opn.adj.comp = apply(opn.adj.comp, 2, function(x) tapply(x, rownames(opn.adj.comp), sum, na.rm = TRUE)) Heatmap(opn.adj.comp, col = my_palette)
  • 53. And now the really exciting bit! How do these neurons connect to each other?
  • 54. Other ways to look at connectivity ## What about OPN connectivity to neurons not in this set of OPNs? ### First, is there a common partner to all OPNs? common = neuprint_common_connectivity(opn.info$bodyid, prepost = "PRE") ### could use 'post' for downstream dim(common) ### What about the food hub PNs? ### The glomerulus DM1 is interesting, because it is involved in an axo-axonic ### 'food odour' related community in the lateral horn (Bates & Schlegel et al. 2020) DM1.opn.info = subset(opn.info, grepl("DM1|DM3|DM4|VM3|VA4",name)) DM1.common = neuprint_common_connectivity(DM1.opn.info$bodyid, prepost = "PRE") dim(DM1.common) DM1.common.meta = neuprint_get_meta(colnames(DM1.common)) # what are they? View(DM1.common.meta) # Huhh, local neurons, the APL and some LH stuff
  • 55. Other ways to look at connectivity ## We can also get all of the neurons in the database that connect to the ### query neurons, either upstream or downstream of them DM1.opn.connected = neuprint_connection_table(DM1.opn.info$bodyid, prepost = "POST") ### In which brain region are these partners? table(DM1.opn.connected$roi)
  • 56. Other ways to look at connectivity ## Let's have a look at what the strongest downstream partners look like DM1.opn.connected.strong = subset(DM1.opn.connected,weight>100, prepost = "POST") DM1.targets = neuprint_read_neurons(DM1.opn.connected.strong$partner) nopen3d() plot3d(DM1.targets, lwd = 2, col = sample(lacroix,length(DM1.targets),replace=TRUE)) View(DM1.targets[,])
  • 57. Other ways to look at connectivity ## So there are three lateral horn neuron targets of the axon there ### c("359214479", "359891881", "511616870"), found using nat::find.neuron ### Let's move forward with those lhns = c(359214479, 359891881, 511616870) lhn.cols = c(lacroix[["marine"]],lacroix[["blue"]],lacroix[["green"]]) names(lhn.cols) = DM1.targets[lhns,"type"] lh.targets = DM1.targets[lhns] clear3d() plot3d(lh.targets, lwd = 2, col = c(lacroix[["marine"]], lacroix[["blue"]], lacroix[["green"]])) plot3d(subset(opns,grepl("DM1",name)),lwd=2,col=lacroix[["orange"]])
  • 58. Let's make a network graph to see how different OPNs can reach these LHNs ### Which other OPNs impinge on it?, vwhatever path? shortest.paths = data.frame() for(lhn in lhns){ for(b in opn.info$bodyid){ # PN -> LHN only sp = neuprint_get_shortest_paths(body_pre = b, body_post = lhn, weightT = 10) dupe = ifelse( is.na(which(duplicated(sp$to))[1]),nrow(sp),which(duplicated(sp$to))[1]) shortest = sp[1:dupe,] if(nrow(shortest)>0 & nrow(shortest)<5 ){ shortest$order.to = paste(1:nrow(shortest), nrow(shortest), sep = "/") shortest$order.from = paste(1:nrow(shortest)-1, nrow(shortest), sep = "/") shortest[1,"order.from"] = opn.info[as.character(b),"glomerulus"] shortest[nrow(shortest),"order.to"] = DM1.targets[lhn,"type"] shortest.paths = rbind(shortest.paths, shortest) } } }
  • 59. Let's make a network graph to see how different OPNs can reach these LHNs paths = aggregate(list(weight = shortest.paths$weight), list(order.from = shortest.paths$order.from, order.to = shortest.paths$order.to), sum) n = network(paths, matrix.type = "edgelist", ignore.eval = FALSE, layout = "fruchtermanreingold", names.eval = "weight", directed = TRUE) n = ggnetwork(n, cell.jitter = 0.75, arrow.gap = 0.01) # Set colours orders = unique(c(paths$order.to,paths$order.from)) order.cols = rep("grey30",length(orders)) names(order.cols) = orders gloms = unique(opn.info$glomerulus) opn.cols = rep(lacroix[["orange"]],length(gloms)) names(opn.cols) = gloms opn.cols = c(opn.cols,lhn.cols,order.cols[!names(order.cols)%in%c(names(lhn.cols),names(opn.cols))])
  • 60. Let's make a network graph to see how different OPNs can reach these LHNs # Plot ggplot(n, aes(x = x, y = y, xend = xend, yend = yend)) + geom_edges(aes(color = vertex.names), curvature = 0.05, arrow = arrow(length = unit(6, "pt"), type = "closed")) + geom_nodes(aes(color = vertex.names, size = 6)) + geom_edgetext(aes(label = weight, color = vertex.names), fill = NA) + geom_nodelabel_repel(aes(color = vertex.names, label = vertex.names), fontface = "bold", box.padding = unit(1, "lines")) + scale_color_manual(values = opn.cols) + scale_fill_manual(values = opn.cols) + theme_blank() + guides(color = FALSE, shape = FALSE, fill = FALSE, size = FALSE, linetype = FALSE) + ylab("") + xlab("")
  • 61. Let's make a network graph to see how different OPNs can reach these LHNs
  • 62. That's it for now! If something is broken or you want to suggest a new feature, contact us preferably by making an issue on GitHub https://github.com/natverse/neuprintr/issues