context("core neuron methods")
test_that("we can make a neuron",{
x=Cell07PNs[[1]]
x2=do.call('neuron',x)
expect_equal(x,x2)
})
testd=data.frame(PointNo=1:6,Label=2L,
X=c(1:5,3),Y=c(rep(1,5),2),Z=0,W=NA,
Parent=c(-1,1:4,3))
testn=as.neuron(testd)
# wrapper for as.neuron that adds some fake vertex data to avoid warning
# (real neurons will always have vertex data so as.neuron.ngraph expects this)
as.neuron2<-function(ng, ...) {
fakeVertexData=matrix(1,ncol=4,nrow=igraph::vcount(ng))
colnames(fakeVertexData)=c("X","Y","Z","W")
as.neuron(ng, vertexData = fakeVertexData, ...)
}
test_that("as.neuron.ngraph works",{
g<-as.ngraph(testn)
cn=as.neuron(g,vertexData=testd,origin=1)
expect_equal(testn$SegList,cn$SegList)
expect_equal(testd,cn$d)
# vertex names with gaps
g=ngraph(c(2,4,4,3,3,6,6,9,6,7),vertexnames=c(2:4,6,7,9))
sl=seglist(c(1,3,2,4),c(4,5),c(4,6))
expect_equal(as.seglist(g,origin=1),sl)
expect_equal(as.neuron2(g,origin=2)$SegList,sl)
# same but no origin specified (should give same result)
expect_equal(as.neuron2(g)$SegList,sl)
# same but different origin
sl2=seglist(c(3,1),c(3,2,4),c(4,5),c(4,6))
expect_equal(as.neuron2(g,origin=4)$SegList,sl2)
# same connectivity but one extra (floating) point at end
g=ngraph(c(2,4,4,3,3,6,6,9,6,7),vertexnames=c(2:4,6,7,9,10))
n=as.neuron2(g,origin=4)
expect_equal(n$SegList,sl2)
expect_equal(n$nTrees,2)
expect_equal(n$SubTrees,list(sl2,seglist(7)))
# same connectivity but with extra (floating) points at start and end
g=ngraph(c(2,4,4,3,3,6,6,9,6,7),vertexnames=c(1:4,6,7,9,10))
# this will shift all vertex ids by 1
sl3=as.seglist(lapply(sl2,'+',1))
n=as.neuron2(g,origin=4)
expect_equal(n$SegList,sl3)
expect_equal(n$nTrees,3)
expect_equal(n$SubTrees,list(sl3,seglist(1),seglist(8)))
# 3 separate subgraphs of length 3,4,5
g=ngraph(c(0,1,1,2, 3,4,4,5,5,6, 7,8,8,9,9,10,10,11),vertexnames=0:11)
n=as.neuron2(g,origin=0)
expect_equal(n$SegList,seglist(c(1,2,3)))
n2=as.neuron2(g,origin=3)
expect_equal(n2$SegList,seglist(c(4,5,6,7)))
n3=as.neuron2(g,origin=7)
expect_equal(n3$SegList,seglist(c(8,9,10,11,12)))
# check that it picks largest subgraph when no origin specified
n4=as.neuron2(g)
expect_equal(n4,n3)
expect_equal(as.seglist(n), n$SegList)
expect_error(as.neuron(g, vertexData=matrix(ncol=4,nrow=igraph::vcount(g)+1)),
info="as.neuron.ngraph fails when vertexData has too many rows")
})
test_that("use as.seglist with neurons",{
g=ngraph(c(0,1,1,2, 3,4,4,5,5,6, 7,8,8,9,9,10,10,11),vertexnames=0:11)
n=as.neuron2(g,origin=0)
full_seg_list=list(seglist(c(1,2,3)), seglist(c(8,9,10,11,12)),
seglist(c(4,5,6,7)))
full_seg_list_flat=seglist(c(1,2,3), c(8,9,10,11,12), c(4,5,6,7))
expect_equal(as.seglist(n, all=FALSE), full_seg_list[[1]])
expect_equal(as.seglist(n, all=TRUE), full_seg_list)
expect_equal(as.seglist(n, all=TRUE, flatten = TRUE), full_seg_list_flat)
g2=ngraph(c(2,4,4,3,3,6,6,9,6,7),vertexnames=c(2:4,6,7,9))
sl2=seglist(c(1,3,2,4),c(4,5),c(4,6))
n2=as.neuron2(g2, origin=2)
expect_false(inherits(as.seglist(n2, all=TRUE), 'seglist'),
info='should be a list of seglists')
expect_equal(as.seglist(n2, all=FALSE), sl2)
expect_equal(as.seglist(n2, all=TRUE, flatten=TRUE), as.seglist(n2, all=FALSE))
})
test_that("we can set NeuronName when there is no input file",{
g=ngraph(c(0,1,1,2, 3,4,4,5,5,6, 7,8,8,9,9,10,10,11),vertexnames=0:11)
n=as.neuron2(g, origin=0, NeuronName="MySpecialNeuron")
expect_equal(n$NeuronName, "MySpecialNeuron")
})
context("all.equal.neuron")
test_that("all.equal.neuron behaves", {
n=Cell07PNs[[1]]
expect_equal(n, Cell07PNs[[1]])
n2=n
n2$NeuronName=NULL
expect_match(all.equal(n, n2, fieldsToCheck = NA), "missing")
expect_equal(n, n2, CheckSharedFieldsOnly=TRUE)
})
context("neuron arithmetic")
test_that("operator equivalence for neuron arithmetic", {
nn=Cell07PNs[1:2]
expect_equal(nn*0.5, nn/2)
expect_equal(nn+(-2), nn-2)
expect_equal(-nn, nn*-1)
n=Cell07PNs[[1]]
expect_equal(n*0.5, n/2)
expect_equal(n+(-2), n-2)
expect_equal(-n, n*-1)
expect_equal(n2 <- n*2, n*c(2,2,2,1))
n2$d$W=n2$d$W*2
expect_equal(n2, n*c(2,2,2,2))
})
context("neuron plotting")
test_that("we can plot neurons in 2D", {
my.pdf=tempfile(fileext = '.pdf')
on.exit(unlink(my.pdf))
pdf(file = my.pdf)
plottedVertices <- plot(Cell07PNs[[1]])
plot(Cell07PNs[[2]], soma=1, WithAllPoints = T, PlotAxes = 'YZ')
dev.off()
plottedVertices.expected <- structure(list(PointNo = c(34L, 48L, 51L, 75L, 78L, 95L, 98L, 99L, 108L, 109L, 115L, 119L, 135L, 143L, 160L, 169L, 1L, 42L, 59L, 62L, 80L, 85L, 96L, 100L, 102L, 112L, 117L, 121L, 134L, 148L, 154L, 165L, 172L, 180L, 1L), X = c(220.98664855957, 228.44807434082, 227.528900146484, 250.583908081055, 250.374450683594, 263.807434082031, 266.267333984375, 266.755706787109, 272.031951904297, 272.292327880859, 274.804351806641, 277.783020019531, 272.748596191406, 278.978912353516, 278.77392578125, 282.149841308594, 186.86604309082, 224.706741333008, 229.634338378906, 226.885482788086, 249.886367797852, 253.009902954102, 264.080108642578, 266.322326660156, 267.545959472656, 271.076171875, 274.612823486328, 277.391998291016, 287.121398925781, 281.795806884766, 276.655090332031, 278.328735351562, 282.306945800781, 289.536407470703, 186.86604309082), Y = c(100.98698425293, 95.4461364746094, 92.0755767822266, 96.9142990112305, 94.3393630981445, 99.7057647705078, 100.097373962402, 99.1845474243164, 104.97306060791, 104.184257507324, 102.846878051758, 103.363876342773, 105.580902099609, 101.788757324219, 109.390472412109, 110.003799438477, 132.709320068359, 109.863616943359, 92.3063659667969, 90.3632507324219, 93.5907897949219, 90.9490432739258, 98.5338973999023, 98.7324066162109, 98.5985946655273, 102.672882080078, 100.920608520508, 102.191482543945, 101.433647155762, 96.6398696899414, 95.0980911254883, 113.756271362305, 111.93212890625, 111.960144042969, 132.709320068359 )), .Names = c("PointNo", "X", "Y"), row.names = c("34", "48", "51", "75", "78", "95", "98", "99", "108", "109", "115", "119", "135", "143", "160", "169", "1", "42", "59", "62", "80", "85", "96", "100", "102", "112", "117", "121", "134", "148", "154", "165", "172", "180", "1.1"), class = "data.frame")
expect_equal(plottedVertices, plottedVertices.expected)
})
test_that("we can plot neurons in 3D", {
options(nat.plotengine='rgl')
plottedLines <- plot3d(Cell07PNs[[1]], soma=3, WithText=T, WithNodes = T, WithAllPoints=T)$lines
expect_gt(plottedLines, 0)
options(nat.plotengine='plotly')
plottedLines <- plot3d(Cell07PNs[[1]], soma=3, WithText=T, WithNodes = T, WithAllPoints=T)
expect_type(plottedLines, "list")
})
test_that("we can plot dotprops in 2D", {
expect_null(plot(kcs20[[1]]))
expect_silent(plot(kcs20[1], soma=T))
})
test_that("we can plot dotprops in 3D", {
options(nat.plotengine='rgl')
plottedSegments <- plot3d(kcs20[[1]])$segments
expect_gt(plottedSegments, 0)
options(nat.plotengine='plotly')
plottedSegments <- plot3d(kcs20[[1]])
expect_type(plottedSegments, "list")
})
context("neuron seglengths/resampling")
test_that("we can calculate seglengths of neuron", {
expect_equal(seglengths(testn), c(2, 2, 1))
expect_equal(seglengths(testn, all=TRUE), c(2, 2, 1))
expect_equal(seglengths(testn, all=TRUE, flatten=FALSE), list(c(2, 2, 1)))
expect_equal(seglength(matrix(1:3,ncol=3)), 0)
# lengths of each edge
expect_equal(seglengths(testn, sumsegment = FALSE, all=TRUE, flatten = FALSE),
list(list(c(1, 1), c(1, 1), 1)))
# single segment neuron
n=as.neuron(data.frame(PointNo=1:5,Label=2L,
X=c(1:5),Y=c(rep(1,5)),Z=0,W=NA,
Parent=c(-1,1:4)))
expect_equal(seglengths(n), 4)
expect_equal(seglengths(n, sumsegment = FALSE), list(c(1,1,1,1)))
# multitree neuron
# break a segment off into separate tree
testd2=testd
testd2$Parent[5:6]=c(-1,5)
n2=as.neuron(testd2)
expect_equal(seglengths(as.neuron(n2),all = T), c(3, sqrt(5)))
})
test_that("we can resample neurons", {
s=testn$SegList[[1]]
expect_equivalent(resample_segment(testn$d[s, c("X", "Y", "Z", "W", "Label")], 1),
testn$d[2, c("X", "Y", "Z", "W", "Label"), drop=FALSE])
s3=testn$SegList[[3]]
expect_equivalent(resample_segment(testn$d[s3, c("X", "Y", "Z")], 0.5),
testn$d[s3[1], c("X", "Y", "Z"), drop=F]+c(0,0.5,0))
# real life example with duplicate point
d=matrix(c(33.1389, 33.0951, 33.0876, 33.0971, 33.0001, 32.9394,
32.8519, 32.8519, 32.7398, 32.7247, 32.7854, 32.7911, 32.8006,
32.7988, 32.7854, 32.9071, 61.9844, 61.5798, 61.5551, 61.5551,
61.5189, 61.4866, 61.5056, 61.5056, 61.5684, 61.5741, 61.6349,
61.6691, 61.6899, 61.7184, 61.7299, 61.6368, 43.15, 43.15, 43.1,
43.05, 43, 42.95, 42.9, 42.9, 42.85, 42.8, 42.75, 42.7, 42.65,
42.6, 42.55, 42.5, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2),
ncol=4, dimnames = list(NULL, c("X", "Y", "Z", "W")))
baseline <-
matrix(c(32.726738385323, 61.5733305432887, 42.8067496202749,-2),
ncol = 4, dimnames = list(NULL, c("X", "Y", "Z", "W")))
expect_silent(rsd <- resample_segment(d, 1))
expect_equal(rsd, baseline, tolerance=1e-6)
expect_is(resampled<-resample(testn, 1.2), 'neuron')
expect_equal(seglengths(resampled), seglengths(testn))
expect_is(resampled.5<-resample(testn, 0.5), 'neuron')
expect_equal(seglengths(resampled.5), seglengths(testn))
expect_is(resampled1<-resample(testn, 1), 'neuron')
expect_equal(seglengths(resampled1), seglengths(testn))
set.seed(42)
g=ngraph(c(0,1,1,2, 3,4,4,5,5,6, 7,8,8,9,9,10,10,11),vertexnames=0:11)
n=as.neuron(g,origin=3, vertexData = matrix(rnorm(12*4),ncol=4, dimnames = list(NULL, c("X","Y","Z","W"))))
expect_is(n1<-resample(n,1), "neuron")
expect_equivalent(xyzmatrix(n1)[n1$StartPoint,], xyzmatrix(n)[n$StartPoint,])
expect_true(all(seglengths(n1, all = T) < seglengths(n, all = T)))
n=Cell07PNs[[1]]
expect_is(n1<-resample(n, 1), 'neuron')
expect_true(igraph::graph.isomorphic(segmentgraph(n1), segmentgraph(n)))
nodes.n=c(n$BranchPoints, n$EndPoints)
nodes.n1=c(n1$BranchPoints, n1$EndPoints)
expect_equivalent(xyzmatrix(n1)[nodes.n1,], xyzmatrix(n)[nodes.n,])
})
test_that("we can normalise an SWC data block", {
# nb need to remove rownames for this old neuron
d=Cell07PNs[[1]]$d
row.names(d)=NULL
expect_equal(normalise_swc(Cell07PNs[[1]]$d[-2], defaultValue=list(Label=2L)),
d)
expect_error(normalise_swc(Cell07PNs[[1]]$d[-2], ifMissing = 'stop'),
regexp = "Columns.*are missing")
})
test_that("we can subset a neuron", {
n=Cell07PNs[[1]]
# keep vertices if their X location is > 2000
expect_is(n1<-subset(n, X>200), 'neuron')
npoints_dropped=sum(xyzmatrix(n)[,1]<=200)
expect_equal(nrow(n1$d), nrow(n$d)-npoints_dropped)
# diameter of neurite >0
expect_equal(subset(n, W>0),n)
expect_equal(subset(n, W>1), subset(n, W<=1, invert=TRUE))
# first 50 nodes
expect_equal(subset(n,1:50)$d$PointNo, 1:50)
# function
f <- function(xyz) xyz[,3]>100
expect_equal(subset(n, f), subset(n, Z>100))
})
test_that("we can subset a neuron with a vertex sequence", {
n = Cell07PNs[[1]]
n_graph_dfs = igraph::graph.dfs(as.ngraph(n), root = 48, mode = "out", unreachable = FALSE)
expect_is(n_subset <- subset(n, n_graph_dfs$order, invert = F), 'neuron')
expect_is(n_subset <- subset(n, n_graph_dfs$order, invert = T), 'neuron')
})
context("manipulate neurons")
sample_neuron = Cell07PNs[[1]]
test_that("Simplify a neuron to n-branchpoints", {
sample_branches=simplify_neuron(sample_neuron, n = 1, invert = F)
expect_equal(length(branchpoints(sample_branches)),1)
sample_branches2=simplify_neuron(sample_neuron, n = 2, invert = F)
expect_equal(length(branchpoints(sample_branches2)),2)
})
test_that("Stitch a neuron that has been fragmented", {
sample_main=simplify_neuron(sample_neuron, n = 1, invert = F)
sample_branches=simplify_neuron(sample_neuron, n = 1, invert = T)
expect_gt(sample_branches$nTrees,1)
#For neuronlist..
sample_fragment <- neuronlist(sample_main,sample_branches)
sample_whole <- stitch_neurons_mst(sample_fragment)
expect_equal(sample_whole$nTrees,1)
#For neuron..
sample_whole <- stitch_neurons_mst(sample_branches)
expect_equal(sample_whole$nTrees,1)
#Stitching based on closest points..
#Actually this doesn't guarentee only one tree as the stitching is done at only one closest point..
#Hence the strategy here is to test if the merged neuron actually has points from both the parents.
expect_warning(sample_whole <- stitch_neuron(sample_main,sample_branches),
"Multiple origins found! Using first origin.")
expect_equal(sample_whole$NumPoints, sample_main$NumPoints + sample_branches$NumPoints)
expect_null(stitch_neurons(neuronlist()))
expect_s3_class(stitch_neurons(as.neuronlist(sample_fragment[[1]])), "neuron")
expect_warning(sample_whole <- stitch_neurons(sample_fragment),
"Multiple origins found! Using first origin.")
expect_equal(sample_whole$NumPoints,sample_fragment[[1]]$NumPoints + sample_fragment[[2]]$NumPoints )
#Check if it can stich a actual fragmented neuron from neuprintr
fragneuron <- readRDS("testdata/neuron/fragmented_neuron.rds")
expect_gt(fragneuron$nTrees,1)
expect_warning(sample_whole <- stitch_neurons_mst(fragneuron, threshold = 1000),
regexp = "Could not connect two vertices as edge length")
expect_equal(sample_whole$nTrees,1)
})
test_that("nodes distal to a given node", {
n = Cell07PNs[[1]]
rootnode <- rootpoints(n)
nodeorder <- distal_to(n, node.pointno = rootnode) #Actually listing all the nodes distal to the rootnode here..
expect_equal(length(nodeorder),n$NumPoints) #This should contain all the nodes in the neuron
nodeorder2 <- distal_to(n, node.pointno = n$NumPoints/2) #Take a node in the middle of the neuron run..
reducednodeorder <- nodeorder[nodeorder>=min(nodeorder2)]
#Just comparing the reduced path(computed originally from the root) with the distal node list path
expect_equal(reducednodeorder,nodeorder2)
})
test_that("prune twigs of a neuron", {
n = Cell07PNs[[1]]
pruned_neuron <- prune_twigs(n, twig_length = 5)
#simple test comparing the number of edges after pruning.
expect_lt(pruned_neuron$NumSegs,n$NumSegs)
})
test_that("rerooting of neurons", {
n = Cell07PNs[[1]]
# args check works correctly
expect_error(reroot(n), "Exactly one argument")
# test rerooting by idx
r_n = reroot(n, 5)
expect_equal(r_n$StartPoint, 5)
# test rerooting by point no
r_n = reroot(n, pointno=7)
expect_equal(r_n$StartPoint, 7)
# test rerooting by point
idx <- 141
pnt <- as.numeric(n$d[idx,c("X","Y","Z")])
r_n = reroot(n, point=pnt)
expect_true(all(r_n$d[r_n$StartPoint,c("X","Y","Z")]-pnt == 0))
})
test_that("rerooting neuronlist", {
pns<-Cell07PNs[1:3]
# args check works correctly
expect_error(reroot(pns, idx = 3, pointno = 4), "Exactly one argument")
# test rerooting by idx
rpns=reroot.neuronlist(pns, idx=c(1,2,3))
expect_equal(rpns[[2]]$StartPoint, 2)
# test rerooting by point
points=pns[[1]]$d[12:14,c("X","Y","Z")]
rpns=reroot.neuronlist(pns, point = points)
expect_equal(rpns[[1]]$StartPoint, 12)
points=as.matrix(points)
rpns=reroot.neuronlist(pns, point = points)
expect_equal(rpns[[1]]$StartPoint, 12)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.