Skip to content

Commit f6b0a55

Browse files
authored
Merge pull request #441 from imagej/snt-agentic-scripting
SNT: Revise documentation for (agentic) scripting
2 parents 78118bf + 0d08bdd commit f6b0a55

4 files changed

Lines changed: 126 additions & 9 deletions

File tree

‎_pages/plugins/snt/big-data.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,5 @@ BVV's 3D renderer requires a multi-resolution pyramid, and a single GPU texture
111111
## See Also
112112

113113
- [SNT Stream](./snt-stream): Tracing on streamed data, differences from in-core tracing, channel unmixing, materialized crops, and editing
114+
- [Profiling SNT](./extending#profiling-snt): Monitoring latencies and performance to fine-tune big-data loading
114115
- [Key Shortcuts](./key-shortcuts): Shortcuts for both traditional and streamed canvases

‎_pages/plugins/snt/extending.md‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,43 @@ To use SNT as a software library in your own project, simply add SNT as a maven
2121
<dependency>
2222
<groupId>org.morphonets</groupId>
2323
<artifactId>SNT</artifactId>
24-
<version>4.2.0</version> <!-- only required if pom-scijava is not being used as parent pom -->
24+
<version>5.0.21</version> <!-- only required if pom-scijava is not being used as parent pom -->
2525
</dependency>
2626
```
2727
See e.g., [this forum thread](https://forum.image.sc/t/minimal-autotrace-code-for-snt-java/51654/15) for a concrete example of SNT being used as a software library.
2828

29+
## Profiling SNT
30+
31+
You can profile SNT's ability to parse [Big Data](./big-data) using the following flags/parameters:
32+
33+
| Flag | Default | Effect |
34+
|---|---|---|
35+
| `snt.profile` | false | Master switch. Prints the summary table (timings, per-level `cell.load`, decoded MB, EDT stall counts) every few seconds |
36+
| `snt.profile.n5` | false | Also times every N5/Zarr reader call, e.g. `n5.readChunk` and peak concurrent reads. Needs `snt.profile` |
37+
| `snt.profile.slow` | false | Logs each slow call as it happens (highly verbose) |
38+
| `snt.profile.edt` | false | Starts the EDT stall monitor |
39+
| `snt.profile.edt.dump` | false | On a stall, dumps the EDT's stack trace. Needs `snt.profile.edt` |
40+
| `snt.profile.slowMs` | 30 | Threshold for "slow call" logging |
41+
| `snt.profile.stallMs` | 150 | How long the EDT must be unresponsive to count as a stall |
42+
| `snt.profile.reportSec` | 10 | Seconds between summary tables |
43+
44+
### BVV Streaming
45+
46+
| Flag | Default | Effect |
47+
|---|---|---|
48+
| `snt.bvv.fetchers` | 64 remote, cores-1 local | Number of tile fetcher threads. It overrides the Preferences entry |
49+
| `snt.bvv.maxCell` | 256 | Upper limit for the cell size, which otherwise matches the chunk size |
50+
| `snt.bvv.noQueueSync` | false | Turns off queue sync (for comparison runs) |
51+
| `snt.bvv.levelPriority` | false | Enables coarse-levels-first priorities (experimental) |
52+
| `snt.bvv.moveAA` | false | Keeps overlay anti-aliasing while the view is moving |
53+
54+
You can pass each as _-Dname=value_ pairs to the JVM startup, e.g.:
55+
56+
```bash
57+
cd /path/to/fiji/folder
58+
./fiji -Dsnt.profile=true -Dsnt.profile.n5=true -Dsnt.profile.edt=true -Dsnt.bvv.fetchers=64 -Dsnt.bvv.flatPriority=true
59+
```
60+
2961

3062
## Tubular Geodesics
3163
The Tubular Geodesics plugins were developed several years ago for [Simple Neurite Tracer](/plugins/snt/faq#what-is-the-difference-between-snt-and-simple-neurite-tracer) but remain functional in modern [SNT](/plugins/snt). They can be installed manually as an SNT add-on. Once installed, they allow you to trace on a filtered-version of your image in which neuronal processes (or other tubular structures) are significantly enhanced using [ITK](/software/itk) segmentation. More details on the following pages:

‎_pages/plugins/snt/manual.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ A confirmation dialog shows the connection summary with an option to swap parent
757757
See also this [walkthrough](/plugins/snt/walkthroughs#mergingjoining-paths).
758758

759759
### {{ stream }} Quick Connect... {% include key key='Shift|C' %}
760-
This is an expedite strategy for branching off paths, only available in [Stream mode](./stream-mode):
760+
This is an expedite strategy for branching off paths, only available in [Stream mode](./snt-stream):
761761

762762
1. Press {% include key keys='Shift|C' %} (or choose _Quick Connect..._ from the contextual menu) with the cursor near the node of the edited path that should be connected
763763
2. Move the cursor over the node to connect to: the cursor snaps to the closest node of any other path (within 150 pixels), a dotted line shows the link, and the status message reports the gap

‎_pages/plugins/snt/scripting.md‎

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ update-site: Neuroanatomy
2020
The complete API is hosted at [javadoc.scijava.org/SNT](https://javadoc.scijava.org/SNT) (release builds; updated on major releases) and at [morphonets.github.io/SNT/](https://morphonets.github.io/SNT/) (always reflects the latest source).
2121

2222
##### Script SNT with an AI Agent
23-
SNT ships a ready-to-use **skill** (a portable prompt file) that primes an AI coding agent (Claude, Gemini, Copilot, Codex, Aider, Cline, Continue, and other agents with web access) with SNT's conventions, API patterns, and anti-patterns. Paste this into your agent's chat to get started:
23+
SNT ships a ready-to-use **skill** (a portable prompt file) that primes an AI coding agent (Claude, Gemini, Copilot, Codex, etc. and other agents with web access) with SNT's conventions, API patterns, and anti-patterns. Paste this into your agent's chat to get started:
2424
```
2525
Fetch https://raw.githubusercontent.com/morphonets/SNT/refs/heads/main/SKILL.md, follow its rules, then help me script SNT.
2626
```
27-
If your agent lacks web access, download [SKILL.md](https://github.com/morphonets/SNT/blob/main/SKILL.md) and paste its contents directly.
28-
27+
If your agent lacks web access, use {% include bc path='Scripts|Develop|Download Agent Skill (SKILL.md)...' %} to save the file (by default into a folder named *snt*), and place it in your agent's skills directory (e.g., *.claude/skills/snt/SKILL.md*) or paste its contents directly. Agents can also use the [Develop helper scripts](#develop-menu) to look up the API installed in your Fiji and to inspect the state of an SNT session. **See [Agentic Scripting](#agentic-scripting) for details**.
2928
{% endcapture %}
3029
{% include notice icon="info" content=api %}
3130

@@ -37,7 +36,7 @@ SNT Scripts are intentionally written in multiple languages to demonstrate flexi
3736

3837
## Bundled Templates
3938
{% include img align="right" src="/media/plugins/snt/snt-scripts-menu.png" width="200px" caption="Scripts menu in main dialog"%}
40-
There are 50+ scripts currently bundled in SNT. These are organized into non-rigid categories: *Analysis* (typically handling quantifications) , *Batch* (Bulk processing of files), *Demos* (teaching examples), *Render* (visualizations), *Skeletons &amp; ROIs* (pixel-based analyses), *Tracing* (Tracing-related tasks), and *Time-lapses* (time-lapse utilities).
39+
There are 50+ scripts currently bundled in SNT. These are organized into non-rigid categories: *Analysis* (typically handling quantifications) , *Batch* (Bulk processing of files), *Demos* (teaching examples), *Develop* (helpers for script and agent development, see [below](#develop-menu)), *Render* (visualizations), *Skeletons &amp; ROIs* (pixel-based analyses), *Tracing* (Tracing-related tasks), and *Time-lapses* (time-lapse utilities).
4140

4241
Bundled scripts can be accessed in two ways:
4342

@@ -52,12 +51,97 @@ There are a couple of ways to have your own scripts appear in SNT's *Scripts* me
5251

5352
Any script saved into Fiji's "scripts" subdirectory containing *SNT* in the filename (e.g., *C:\Users\user\Desktop\Fiji.app\scripts\My_SNT_Script.py* or */home/user/Fiji.app/scripts/My_SNT_Script.py*) will be listed in {% include bc path='Scripts'%} menu:
5453

55-
1. Go to {% include bc path='Scripts|New...'%} from the SNT dialog. You can choose to open an instance of Fiji's Script Editor with preloaded boilerplate code in the scripting language of your choice or to assemble your boilerplate using the [Script Recorder](#script-recorder)
54+
1. Go to {% include bc path='Scripts|Develop|New Script from Template...'%} from the SNT dialog. You can choose to open an instance of Fiji's Script Editor with preloaded boilerplate code in the scripting language of your choice or to assemble your boilerplate using the [Script Recorder](#script-recorder)
5655

5756
2. Save the script in *Fiji.app/scripts/* including 'SNT' anywhere in its file name
5857

5958
3. Run {% include bc path='Scripts|Reload...'%}, and your new script should appear in the full list of scripts found at {% include bc path='Scripts|Full List...'%}.
6059

60+
# Develop Menu
61+
62+
The {% include bc path='Scripts|Develop'%} menu groups tools for writing scripts, whether by hand or with an AI agent:
63+
64+
- **New Script from Template...** and **New Script from Clipboard...** open the Script Editor with boilerplate code or with the code in your clipboard
65+
- **REPL** opens the [REPL](#repl)
66+
- **API Lookup** and **Inspect Session** run the helper scripts described below
67+
- **Download Agent Skill (SKILL.md)...** saves SNT's [agent skill](#script-snt-with-an-ai-agent) to disk
68+
69+
## API Lookup
70+
Lists the public API (*sc.fiji.snt.\**) of the SNT version installed in your Fiji, so that class and method names do not need to be guessed. The *Mode* parameter defines what is listed: *search* (classes and methods matching a keyword), *class* (constructors, methods and fields of a class), *classes* (classes of a package) or *packages*. *Query* is the keyword, class name or package name (case is ignored), and *Output* can be *Console*, *JSON* or *Text window*. Deprecated members are omitted unless *Include deprecated API* is checked. If a class is not found (e.g., it was renamed), similar names are suggested.
71+
72+
## Inspect Session
73+
Reports the state of the SNT session in which it runs as JSON: SNT and Java versions, the image being traced (dimensions and calibration), and the number of paths and trees (with cable length, branches and tips for each tree). A reconstruction can be loaded first, and the report can be saved to a file. Run from the Script Editor or the menu, it reports on your live session. Run headlessly, it reports on a fresh one.
74+
75+
## Running the Helpers Headless
76+
Both scripts are bundled in SNT's jar (*script_templates/Neuroanatomy/Develop/*) and can be run from the command line, which is how agents use them:
77+
78+
{% highlight bash %}
79+
fiji --headless --run API_Lookup.groovy 'mode="class",query="TreeStatistics",output="JSON"'
80+
fiji --headless --run Inspect_Session.groovy 'reconstruction="/path/to/cell.swc"'
81+
{% endhighlight %}
82+
83+
Output is always printed to the console unless *Text window* is chosen (and a GUI is available).
84+
85+
# Agentic Scripting
86+
87+
An AI agent can write, run and debug SNT scripts for you, provided it knows SNT's conventions and can check its work against the Fiji you have installed. Getting there takes four steps:
88+
89+
1. **Give the agent the skill.** Paste the one-line prompt from [above](#script-snt-with-an-ai-agent), or save the skill with {% include bc path='Scripts|Develop|Download Agent Skill (SKILL.md)...' %} into your agent's skills directory
90+
2. **Let it reach your Fiji.** Agents with a shell (e.g., Claude Code, Codex) can run Fiji headless and use the [Develop helpers](#develop-menu) to verify class names and inspect results. Chat-only agents cannot: paste their script into the Script Editor, run it, and paste back any error
91+
3. **State the goal, inputs and outputs.** What data you have, what you want measured or drawn, and where the result should go
92+
4. **Iterate on test data first.** Ask the agent to try the script on SNT's demo data (e.g., `snt.demoTree()`), then on one of your files, and only then on the whole batch
93+
94+
Things that help: ask for [script parameters](/scripting/parameters) (`#@`) instead of hard-coded paths so the script can be reused; ask it to adapt one of the [bundled templates](#bundled-templates) rather than starting from scratch; and always sanity-check a result you know (e.g., a cell you have measured before). Agents can be confidently wrong, so review a script before running it on irreplaceable data.
95+
96+
## Example Conversation
97+
The following conversation shows a typical flow for a common task. Note how the agent checks the API instead of relying on memory, tests on demo data, and asks before touching the real files.
98+
99+
{% highlight text %}
100+
You: I have a folder of SWC files. I want a CSV with the cable length, number
101+
of branches and mean branch length of each cell. Can you write a script?
102+
103+
Agent: Sure. Two quick questions: should it also search subfolders, and are
104+
the files calibrated in microns (I would report lengths in the units
105+
stored in the reconstructions)?
106+
107+
You: No subfolders. Units are whatever is in the files.
108+
109+
Agent: Understood. I'll adapt SNT's "Measure Multiple Files" template and first
110+
confirm the method names in your Fiji.
111+
> API_Lookup.groovy mode="class" query="TreeStatistics" output="JSON"
112+
TreeStatistics has getMetric(String) and getSummaryStats(String), with
113+
constants LENGTH, N_BRANCHES and BRANCH_LENGTH. Here is the script:
114+
115+
#@ File (label="Input folder", style="directory") dir
116+
#@ File (label="Output CSV", style="save") csv
117+
import sc.fiji.snt.Tree
118+
import sc.fiji.snt.analysis.*
119+
table = new SNTTable()
120+
dir.eachFileMatch(~/.*\.swc/) { f ->
121+
stats = new TreeStatistics(new Tree(f.absolutePath))
122+
table.insertRow(f.name)
123+
table.appendToLastRow("Cable length", stats.getMetric(TreeStatistics.LENGTH))
124+
table.appendToLastRow("N branches", stats.getMetric(TreeStatistics.N_BRANCHES))
125+
table.appendToLastRow("Mean branch length",
126+
stats.getSummaryStats(TreeStatistics.BRANCH_LENGTH).getMean())
127+
}
128+
table.save(csv.absolutePath)
129+
130+
I'll test it on a demo cell before using your folder.
131+
132+
Agent: > fiji --headless --run measure.groovy 'dir="/tmp/demo",csv="/tmp/out.csv"'
133+
The demo file produced a single row of plausible values that match the
134+
statistics SNT reports for that cell in its own dialogs. Running
135+
it on your folder now... done. 48 files measured, saved to results.csv.
136+
One file (cell_17.swc) has a single path and thus a branch length of
137+
zero: you may want to check it.
138+
139+
You: Great. Add the number of tips as well.
140+
141+
Agent: Done: added an "N tips" column (TreeStatistics.N_TIPS). The updated
142+
script and CSV are saved alongside the previous ones.
143+
{% endhighlight %}
144+
61145
# Script Recorder
62146

63147
SNT features a script recorder that similarly to _ImageJ's macro recorder_ converts menu and button clicks into executable code. Note however that while the recorder captures simple commands well, it struggles to capture those that are more complex or particularly interactive.
@@ -75,7 +159,7 @@ As a rule-of-thumb, commands that are simple or do not involve prompts record fl
75159

76160
# REPL
77161

78-
SNT's Scripting REPL (Read–Eval–Print Loop) is opened using {% include bc path='Scripts|New|REPL'%}. It is a [Script Interpreter](/scripting/interpreter) instance with pre-initialized variables that are entry-points to the API of current SNT session. The REPL serves as a commandline prompt with access to all of SNT classes.
162+
SNT's Scripting REPL (Read–Eval–Print Loop) is opened using {% include bc path='Scripts|Develop|REPL'%}. It is a [Script Interpreter](/scripting/interpreter) instance with pre-initialized variables that are entry-points to the API of current SNT session. The REPL serves as a commandline prompt with access to all of SNT classes.
79163
<div align="center">
80164
<img src="/media/plugins/snt/snt-repl.png" alt="Repl" title="SNTService being accessed in SNT's Scripting REPL" width="700px" />
81165
</div>
@@ -131,7 +215,7 @@ Direct access to the SNT API from the [Python](https://www.python.org/) programm
131215

132216
# Fiji Scripting
133217

134-
Scripting in Fiji's script editor is perhaps best done using Groovy and Jython. The latter as quite good autocompletion for objects that are not script parameters. The best way to start a new script is by choosing a boilerplate {% include bc path='Scripts|New|From Template...'%} in SNT or {% include bc path='Neuroanatomy|Boilerplate|'%} in the script Editor. These templates hold boilerplate code in several programming languages (namely [BeanShell](/scripting/beanshell), [Groovy](/scripting/groovy) and [Jython](/scripting/jython)), and include the most essential imports and [script parameters](/scripting/parameters) to facilitate rapid development.
218+
Scripting in Fiji's script editor is perhaps best done using Groovy and Jython. The latter as quite good autocompletion for objects that are not script parameters. The best way to start a new script is by choosing a boilerplate {% include bc path='Scripts|Develop|New Script from Template...'%} in SNT or {% include bc path='Neuroanatomy|Boilerplate|'%} in the script Editor. These templates hold boilerplate code in several programming languages (namely [BeanShell](/scripting/beanshell), [Groovy](/scripting/groovy) and [Jython](/scripting/jython)), and include the most essential imports and [script parameters](/scripting/parameters) to facilitate rapid development.
135219

136220
{% capture text %}
137221
For serious scripting, Fiji's Script Editor may not be powerful enough for your needs. The most robust way to script SNT in Groovy

0 commit comments

Comments
 (0)