Closed tferr closed 1 year ago
I did not have the time to look at this carefully, but just wanted to lay down the 4 (sub) issues (likely related) in this report by @jkopsick:
Useful jython snippet for initial troubleshooting:
from sc.fiji.snt.io import MouseLightLoader
from sc.fiji.snt.analysis import TreeStatistics
from sc.fiji.snt.gui import MeasureUI
# Non-GUI
loader = MouseLightLoader("AA0091")
axn = loader.getTree("axon")
stats = TreeStatistics(axn)
print(stats.getCableLength())
# GUI
mui = MeasureUI([axn])
mui.setVisible(True)
@jkopsick, an update/explanation on this:
On the getCableLength() mistmatch: In the early days, we were computing lengths in compartments by manual iteration. When @carshadi implemented graph support we refactored things to adopt the more efficient graph parsing. But - it seems- the refactoring was defective and there was still a method in TreeAnalyzer - that the GUI uses because that option already existed in the GUI early on- that was mixing things up. I think we never noticed it before because that method was excluded from the Junit tests. This should now be fixed and v4.1.15 released yesterday has this fix. It Would be great if you could confirm on your end.
Unfortunately, I did not have yet time to look at the other issues...
Apologies for the long delay on this. the differences in cable length are caused by modifications in the CNG version of the SWC file. The following groovy script demonstrates this:
import sc.fiji.snt.*
import sc.fiji.snt.analysis.*
import sc.fiji.snt.io.*
cellId = "AA0091"
loader = new NeuroMorphoLoader()
println("# Comparing Source/CNG versions for neuron " + cellId)
loader.enableSourceVersion(true)
tree1 = loader.getTree(cellId)
tree1.setLabel("Source version")
loader.enableSourceVersion(false)
tree2 = loader.getTree(cellId)
tree2.setLabel("CNG version")
for (tree in [tree1, tree2]) {
stats = new TreeStatistics(tree)
println(tree.getLabel())
println(" Total cable length: " + stats.getCableLength())
for (type in tree.getSWCTypes()) {
stats.restrictToSWCType(type)
println(" sub-compartment " + Path.getSWCtypeName(type, false))
println(" cable length: " + stats.getCableLength())
println(" no. nodes: " + stats.getNNodes())
stats.resetRestrictions()
}
}
result:
# Comparing Source/CNG versions for neuron AA0091
Source version
Total cable length: 7940.740260123613
sub-compartment soma
cable length: 0.0
no. nodes: 1
sub-compartment axon
cable length: 4835.573615659712
no. nodes: 156
sub-compartment (basal) dendrite
cable length: 3004.0677608769874
no. nodes: 93
CNG version
Total cable length: 7940.417323688646
sub-compartment soma
cable length: 1.9426785632214094
no. nodes: 3
sub-compartment axon
cable length: 4835.355050388459
no. nodes: 156
sub-compartment (basal) dendrite
cable length: 3002.13776844564
no. nodes: 94
In the CNG version soma adopts 3 nodes, as opposed to the single node of the original file. @jkopsick, it would be useful to know why NeuroMorpho performs such modifications. Because the issue does not seem to pertain to SNT, I'm closing this for now.
Submitted by Jeffrey Kopsick:
We noticed a mismatch between the SNT GUI and two SNT scripting interfaces (both Python based: pyimagej and SNT’s Python scripting interface used in the SNT GUI) for computed cable lengths of MouseLight projection neurons using SNT. For example, we noticed the following using the AA0091 reconstruction (a Dentate Gyrus Granule Cell):
Scripting interfaces (using getCableLength via TreeStatistics class) compute the axonal length as ~33.34 microns within the dentate gyrus granule layer (CCF Compartment DG-sg; computed using AllenUtils.getCompartment), whereas the GUI reports the axonal length within DG-sg as ~124.89 microns. The GUI does not properly load the breakdown by CCF compartment when called for the dendritic length, so we could not compare between scripting interfaces and GUI. The total axonal cable length irrespective of CCF Compartment in the scripting interfaces were ~4849.19 microns, whereas the GUI reported ~4835.57 microns. The total axonal cable length irrespective of CCF Compartment in the scripting interfaces were ~4849.19 microns, whereas the total axonal cable length using the CCF Compartment “Whole Brain” (via AllenUtils.getCompartment) was ~4682.27 microns. However, total cable length (axonal + dendritic) irrespective of CCF compartment is the same when computed in either the GUI or the scripting interfaces, with a total cable length of ~4849.19 (axonal) + ~3091.55 (dendritic) = ~7940.74 microns; this computation for the total cable length is ~2.27 microns off the L-measure computation for this same reconstruction in NeuroMorpho (~7938.47 microns).
Digging through the SNT source code on GitHub, we believe that the GUI and scripting interfaces should be using the same compartment meshes to make the cable length computation, so in theory these should be the same. So we are uncertain as to what is leading to this discrepancy and wanted to bring it to both of your attention. There could be a difference in the cable length computation that is different between scripting interface and GUI, or the use of different meshes, yet based on the above we would assume it is not the cable length computation given that the total length irrespective of mesh matches in scripting interfaces and GUI, and the estimate is very similar to what is reported in L-measure. Any help in resolving this matter would be greatly appreciated!
Thanks and best,