Simple Neurite Tracer - Changing Cell ID

Is it possible to change the cell ID tag for individual paths generated by SNT during the tracing process?
The reason is that when a student of mine used SNT to reconstruct and measure a series of neurons, they ended up with different branches of the same neuron having different Cell ID tags (probably due to accidental creation of single point selections during the tracing process that were interpreted as new cell soma). An example of the path manager is shown in the screenshot below. Note that the cell ID tag for path (0) is Cell 4, but that the connected subbranches have a cell ID tag of Cell 7.
image

This seems to cause problems trying to measure the neurite parameters.
Using the SNT-Measure function opens the following dialog:
image

Selecting ‘All’ results in an error message saying ‘The path “Path (9) |Cell 7|” is connected to other selected paths, but wasn’t itself selected.’

Selecting a specific cell from the drop down list results in an error saying ‘ERROR] Module threw exception
java.lang.IllegalArgumentException: You can only select one connected set of paths for SWC export’

I was hoping that there is an option to edit the cell ID tag for a selection of paths (or to give all connected branches an identical cell ID tag) to make sure that they all have the same tag, which I hope will resolve the problem. However, I haven’t managed to find anything.
Any suggestions would be very welcome.
Thanks,
Volko

@volko, Wow. We have never predicted such a situation. The “Reset All Tags…” command does not reset cell IDs on purpose, to ensure a Path is never assigned to multiple cells.
I guess what would be needed here is a “Rebuild Relationships” command, where all the connections get re-evaluated and rebuilt. Do you mind sharing the .traces file? @arshadic and I could then use it as a test case.

1 Like

@Tiego, Yes, some sort of tool that could make sure that all connected paths have the same Cell ID would be great. Below are some example trace files (I have changed the file extension to .txt as the system wouldn’t accept .trace files. Hopefully, changing the extension back to .trace should work).
Could you also please clarify when the Cell ID tag is changed during neurite tracing. Am I correct in my assumption that this happens when the user makes and confirms a single point selection, which would be considered a soma? Are there other situations when the Cell ID is changed?
Thanks for your help,
Volko

2017.7.17_A_1_1_006.txt (55.9 KB) 2017.7.17_A_1_1_008.txt (42.8 KB) 2017.7.17_A_1_2_014.txt (24.6 KB)

A new cell ID tag is generated when a new rooted structure is detected during a tracing session. Your primary dendrites are disconnected at the soma. SNT (and almost any other software I am aware of) formalizes a neuron as a rooted tree. As such, all analyses that assume such formalism (Strahler, branch point distances, etc.), will trigger that “Multiple rooted structures exist” prompt. A workaround is to define the soma as single-point centroid (SNT does allow for a 3-point representation, but for simplicity I’ll assume you are not interested in the soma volume), and connect all the primary paths to it. This can be done programmatically with the script below. To run it:

  1. Run Plugins>Neuroanatomy>SNT…, and specify the ‘problematic’ file with disconnected paths (No need to access the original image: you can choose display canvas)
  2. Open Fiji’s Script Editor: (File>New>Script… from Fiji’s main menu), and run the following Groovy script:
#@SNTService snt

import sc.fiji.snt.*
import sc.fiji.snt.util.*

// Documentation Resources: https://imagej.net/SNT:_Scripting
// Latest SNT API: https://morphonets.github.io/SNT/

// access the active `Path Manager`
pafm = snt.getPathAndFillManager()

// Retrieve all of the primary paths and all their root nodes
primaryPaths = []
rootNodes = []
for (path in pafm.getPaths()) {
    if (path.isPrimary()) {
        rootNodes.add(path.getNode(0))
        primaryPaths.add(path)
    }
}
if (primaryPaths.size() < 2) {
    snt.getUI().error("Multiple primary paths were not detected, so no need to run this script")
}

// create a new empty Path with the same properties (i.e., spatial calibration)
// of the first path found in the Path Manager list (In SNT, scaling is set on
// a per-Path basis). Assign unique IDs to avoid conflicts with existing IDs
newSoma = pafm.getPath(0).createPath()
newSoma.setIsPrimary(true)
newSoma.setName('soma centroid')
newSoma.setIDs(-1, 1) // path id, cell id

// Add a node to the newly defined path, corresponding to the centroid of
// all other root nodes and add this new single-point path to the manager
newSoma.addNode(SNTPoint.average(rootNodes))
pafm.addPath(newSoma)

// Now connect all of root nodes to it
primaryPaths.eachWithIndex { primaryPath, index ->
    primaryPath.moveNode(0, newSoma.getNode(0))
    primaryPath.setStartJoin(newSoma, newSoma.getNode(0))
}

// Assign the cell id we have've assigned to 'newSoma' to all paths
for (path in pafm.getPaths()) {
    path.setIDs(path.getID(), 1)
    // Update the 'path order' field of paths that were not altered
    if (path.getStartJoins() != null)
        path.setOrder(path.getStartJoins().getOrder()+1)
}

// refresh viewers and run GUI commands to ensure ourselves we are now
// all with a single-root structure:
snt.updateViewers()
snt.getUI().runCommand("Cell ID")
snt.getUI().runCommand("Create Dendrogram")

And here is a before / after comparison (root paths highlighted in green):

Note that the soma centroid is automatically inferred. The script (that currently runs from the GUI, but could run headless for batch processing) also outputs a dendrogram of the cell (in this case your uploaded file 2017.7.17_A_1_1_006.traces), to illustrate how SNT perceives the cell internally:

1 Like

@Tiego, Thanks for the prompt response. The script works perfectly and solves the problem, but now there is a slightly different issue.
One reason why the student didn’t connect the different primary dendrite tress to a single soma is that they wanted the length information for each primary tree (i.e. in the example above one sum each for all branches connected to segments 2, 3, 12 and 17). I tried to do this by assigning each path that contributes to a primary tree a custom tag (D1 for segment 2, D2 for segments 3-11, D3 for segments 12-16 and D4 for segments 17-29) and tick the ‘Distinguish compartments’ in the Measure dialogue. However, that doesn’t seem to work. Am I missing something obvious? Unfortunately the documentation site is still down, so I can’t check the manual.
I also tried to use the 3-point representation of the soma as we are interested in the soma area (not volume as these are 2D images of cultured cells), but I am not quite sure how to define the soma in that way in SNT. Any hints?
Thanks for your help,
Volko

To measure just the primary path:
Path Manager commands operate only on selected paths or all paths if none exist. You simplify need to select the Paths of interest and run “Measure…”: The entry for “cable length” in the measurements table will reflect only the selected paths.

There are many ways to expedite selection of paths using the bottom toolbar:

  1. if you applied a text tag, you can select them in bulk using the “Text filtering field” and the “Highlight all button”.
  2. If you tagged when using a color, then you can use the “Filter by color tags” button.
  3. Importantly you can also select Paths based on morphometric traits. In this particular case filtering by “Path order” (a centrifugal classification scheme that reflects the indention in the hierarchical list of Paths, with root having an order of 1) of 2 would select all of the primary paths (NB: Since we haven’t formally created the “rebuild” command discussed earlier, I edited the script above to ensure tags are rebuilt. Please use the updated script).

On soma area:
I realize now we support loading of three-point somata but we don’t really provide an expedite way to define them. We’ll have to look into. You could use the “Fill Manager” to “fill” the single-point soma path, although we haven’t really tested for blob-like structures, so I’m not sure how well it will work out). However, you can pause SNT using the right-click contextual menu and use any of ImageJ tools to obtain its area.

That is indeed unfortunate. Two workarounds:

  1. Most GUI components offer tooltips (e.g., the tooltip for ‘Distinguish compartments’ checkbox explains that it segregates measurements into branches tagged as “axon” and “dendrites” – cellular compartments --, when such tagging exists.
  2. @arshadic video-tutorials remain accessible on Fiji’s Youtube Channel.

@Tiego: I don’t know why, but I don’t seem to be able to obtain measurements of individual branches even after selecting an individual path in the path manager and using the Analyze->Measure function in the Path Manager window.
For example, selecting just Path (0) (shown below)


produces exactly the same measurements table (line 1 of the SNT Measurements table) as not selecting any path (line 2 of the table) or selecting all paths (line 3 of the table).
This is the resulting SNT measureent table. Note that all three lines are identical:

I watched the YouTube video ‘SNT: Analyzing Reconstructions’ to figure out where I might be going wrong, but I can’t see what I am doing differently. Whatever I do, I don’t seem to be able to get a measurement for just a subset of the paths.
Sorry if I am overlooking something obvious, but any idea what I might be missing?
Thanks,
Volko

Dear @Volko,

You are not doing anything wrong. Somehow that option got accidentally disabled in this release. @arshadic and I just pushed a new version that fixes that issue and adds a couple of more features to the Path Manager that should help you. For future reference here are the changes:

  • Edit>Merge Primary Path(s) Into Shared Root This new command achieves the same as the script above so you don’t have to run it from the Script Editor
  • Edit>Rebuild This is a new “auto-heal” command. It will recompute the hierarchical relationships between paths, in case something got broken after e.g., an interactive script. It also resets IDs of paths and cells.
  • We’ve separated the Analyze>Measure commands into two:
    • Analyze>Measure Path(s): Will measure groups of paths independently of their connectivity. This means that you no longer need to care about disconnected primary paths (i.e, you don’t need to run Edit>Merge Primary Path(s) Into Shared Root…). You can simply measure them exactly as they are. Note however that metrics that require the neuron to be parsed as a rooted tree won’t be available.
    • Edit>Measure Structure(s): Measures complete arbors.

NB: In light of the recent imagej.net downtime, we also tried to improve the descriptions that appear when the cursor pauses over a menu command.

In short, for your particular measurements of primary paths, the procedure should be much more simplified:

  1. Select all primary paths: There are two ways of doing this:
    • Type 1 in the Path Order filtering prompt of the bottom’s toolbar Filter by morphometric trait button, or
    • Run Tag>Morphometry>Path Order to assign order tags then type Order 1 in the filtering box and press Highlight All
  2. Run Analyze>Measure Path(s)

Dear @Tiego,
That’s excellent - I have just tried it and it is working perfectly. These new additions are very helpful. As usual, thank you very much for your prompt assistance.
Very much appreciated.
All the best,
Volko

Welcome to the forum @Flexin,
Cell IDs are unique identifiers automatically assigned to arbor. Every-time a disconnected primary path (i.e., a root) is created, a new ID is created, and is assigned to future children of that primary path. Such IDs are not expected to change during a tracing session during typical usage, unless there are lots of re-arrangements of paths. E.g., Cell IDs will likely change if you disconnect all paths and re-connnect them afterwards.