View source: R/flywire-skeleton.R
skeletor | R Documentation |
You can skeletonise complex neuron meshes using skeletor
skeletor-1.0.0. Skeletor is a
python library and this function wraps a series of skeletor functions in
order to smoothly process neurons for use with the
natverse. Note, the default settings optimise
performance for fast skeletonisation of
flywire meshes. For casual users we
recommend using the 'wave' method, which is fast and simple in terms of
parameters, i.e. it just uses waves
and step_size
. A value of
1 for both often works well.
skeletor(
segments = NULL,
obj = NULL,
mesh3d = FALSE,
save.obj = NULL,
cloudvolume.url = getOption("fafbseg.cloudvolume.url"),
operator = c("umbrella", "contangent"),
clean = FALSE,
remove_disconnected = 10,
theta = 0.01,
radius = TRUE,
ratio = 0.1,
SL = 10,
WH0 = 2,
iter_lim = 4,
epsilon = 0.05,
precision = 1e-06,
validate = TRUE,
method.radii = c("knn", "ray"),
method = c("wavefront", "vertex_clusters", "edge_collapse", "teasar", "tangent_ball"),
heal = TRUE,
heal.k = 10L,
heal.threshold = Inf,
reroot = TRUE,
k.soma.search = 10,
radius.soma.search = 2500,
brain = NULL,
n = 5,
n_rays = 20,
projection = c("sphere", "tangents"),
fallback = "knn",
waves = 2,
step_size = 1,
sampling_dist = 500,
cluster_pos = c("median", "center"),
shape_weight = 1,
sample_weight = 0.1,
inv_dist = 100,
cpu = Inf,
elapsed = Inf,
...
)
reroot_hairball(x, k.soma.search = 10, radius.soma.search = 2500, brain = NULL)
download_neuron_obj(
segments,
save.obj = getwd(),
ratio = 1,
cloudvolume.url = getOption("fafbseg.cloudvolume.url"),
...
)
segments |
The segment ids to fetch (probably as a character vector),
e.g. flywire IDs or hemibrain bodyids. Meshes are read from the specified
CloudVolume ( |
obj |
character. Path of a |
mesh3d |
logical. If |
save.obj |
character. Path to which to save |
cloudvolume.url |
Optional url from which to fetch meshes normally
specified by the |
operator |
Which Laplacian operator to use for mesh contraction.
|
clean |
logical. If |
remove_disconnected |
integer or 'False'. If a number is given and
|
theta |
numeric. Used if |
radius |
logical. Whether or not to return radius information for each
skeleton node. If you want to make use of radii, you will need to have the
|
ratio |
numeric, 0-1. Factor to which to reduce mesh faces. For example, a ratio of 0.5 will reduce the number of faces to 50 percent. |
SL |
numeric. Factor by which the contraction matrix is multiplied for each iteration. In theory, lower values are more likely to get you an optimal contraction at the cost of needing more iterations. |
WH0 |
numeric. Initial weight factor for the attraction constraints. The
ratio of the initial weights |
iter_lim |
integer. Maximum rounds of contractions. |
epsilon |
numeric. Target contraction rate as measured by the sum of all
face areas in the contracted versus the original mesh. Algorithm will stop
once mesh is contracted below this threshold. Depending on your mesh
(number of faces, shape) reaching a strong contraction can be extremely
costly with comparatively little benefit for the subsequent
skeletonisation. Note that the algorithm might stop short of this target if
|
precision |
numeric. Sets the precision for finding the least-square solution. This is the main determinant for speed vs quality: lower values will take (much) longer but will get you closer to an optimally contracted mesh. Higher values will be faster but the iterative contractions might stop early. |
validate |
If |
method.radii |
the method by which to determine each node's radius.
|
method |
Skeletonisation comes in two flavours with different Pros and
Cons. |
heal |
logical. Whether or not, if the neuron id fragmented, to stitch multiple fragments into single neuron using minimum spanning tree. |
heal.k |
integer. The number of nearest neighbours to consider when trying to merge different clusters. |
heal.threshold |
numeric. The threshold distance above which new
vertices will not be connected (default= |
reroot |
logical. Whether or not to re-root the neuron at an estimated 'soma'. A soma is usually a large ball in the neuron, which will skeletonise into something of a hair ball. We can try to detect it quickly and reroot the skeleton there. We do this by finding the nearest leaf nodes to each leaf node, and seeing if they are going off in divergent directions. |
k.soma.search |
integer. The number of leaf nodes to find, around each
leaf node of radius |
radius.soma.search |
numeric. The distance within which to search for fellow leaf nodes for the rerooting process. Will be inaccurate at values that are too high or too low. Should be about the size of the expected soma. |
brain |
a |
n |
For |
n_rays |
integer. For |
projection |
For |
fallback |
For |
waves |
integer. For |
step_size |
integer, Values greater 1 effectively lead to binning of rings. For example a stepsize of 2 means that two adjacent vertex rings will be collapsed to the same center. This can help reduce noise in the skeleton (and as such counteracts a large number of waves) |
sampling_dist |
numeric. For |
cluster_pos |
numeric. For |
shape_weight |
numeric. For |
sample_weight |
numeric.For |
inv_dist |
numeric.For |
cpu |
double (of length one). Set a limit on the total cpu time in seconds. |
elapsed |
double (of length one). Set a limit on the total elapsed cpu time in seconds |
... |
Additional arguments passed to |
x |
a |
This pipeline:
1. Reads specified meshes from a CloudVolume source.
2. Simplifies each mesh (python: skeletor.pre.simplify
)
3. Contract the mesh (python: skeletor.pre.contract
)
4. Skeletonises the mesh (python: skeletor.skeletonize
)
5. Optionally, cleans the mesh (python: skeletor.post.clean_up
)
6. Optionally, add radius information to the skeleton (python:
skeletor.post.radii
)
7. Optionally, heal the skeleton if there are breaks
(nat::stitch_neurons_mst
)
8. Optionally, attempts to re-root the neuron at a 'hairball', i.e.
approximate the soma (reroot_hairball
).
You will therefore need to have a working python3 install of skeletor,
which uses CloudVolume. You do not require meshparty. Please install the
Python skeletor module as described at:
https://github.com/schlegelp/skeletor. You must ensure that you are
using python3 (implicitly or explicitly) as mesh fetching from graphene
servers depends on this. This should normally work: pip3 install
git+git://github.com/schlegelp/skeletor@master
. If you have already
installed skeletor but it is not found, then I recommend editing your
Renviron
file to set an environment variable pointing to the
correct Python. You can do this with usethis::edit_r_environ()
and
then setting e.g. RETICULATE_PYTHON="/usr/local/bin/python3"
.
(Though best practice would be to create a conda environment for your
natverse R sessions and direct R there using your environ file.)
You will need to set up some kind of authentication in order to fetch
volume data for skeletonisation. See
https://github.com/seung-lab/cloud-volume#chunkedgraph-secretjson for
how to get a token and where to save it. You can either save a json snippet
to ~/.cloudvolume/secrets/cave-secret.json
or set an
environment variable (CHUNKEDGRAPH_SECRET="XXXX"
.
Finally you will also need to set an option pointing to your server. This
is the server hosting the mesh data you are interested in. This might look
something like:
options(fafbseg.cloudvolume.url='graphene://https://xxx.dynamicannotationframework.com/segmentation/xxx/xxx')
and you can easily add this to your startup Rprofile
with
usethis::edit_r_profile()
. For example, for the flywire data set, it
is currently:
'graphene://https://prodv1.flywire-daf.com/segmentation/1.0/fly_v31'
.
Roughly in decreasing order of impact on speed:
Ratio: lower ratio = less vertices = faster
epsilon: lower target contraction rate = less steps = faster
SL: faster contraction = pot. less steps to target contraction rate = faster
precision: lower precision = faster least-square computation = faster
sampling_dist: larger dist = faster collapse of mesh into skeleton = faster
A nat::neuronlist
containing neuron skeleton objects.
simple_python
for installation of the necessary Python
packages.
## Not run:
choose_segmentation("flywire")
nx=xform_brain(elmr::dense_core_neurons, ref="FlyWire", sample="FAFB14")
xyz = xyzmatrix(nx)
ids = unique(flywire_xyz2id(xyz[sample(1:nrow(xyz),100),]))
neurons = skeletor(ids, brain = elmr::FAFB14.surf)
plot3d(neurons) # note, in flywire space
plot3d(nx, col="black", lwd =2) # note, in flywire space
# Also plot their meshes
neuron.meshes = read_cloudvolume_meshes(ids)
# We can also just save the .obj files
dir.create("obj")
download_neuron_obj(ids, save.obj = "obj")
# remove
unlink("obj", recurvise = TRUE)
## End(Not run)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.