git:20260506.86420c0 to git:20261014.f405841

59 added, 259 removed. Audit A to A.

---
name: freesurfer-tool
- description: "Use this skill whenever the user wants to process structural MRI data (T1w, T2w, FLAIR, etc.) with FreeSurfer, especially for cortical/subcortical segmentation, surface reconstruction, parcellation, cortical thickness, volume statistics, or full recon-all pipeline. Triggers include: 'freesurfer', 'recon-all', 'segment MRI', 'FreeSurfer processing', 'cortical segmentation', 'subcortical segmentation', 'run recon-all', 'freesurfer T1', 'process brain MRI with freesurfer', 'aseg aparc', or any request to run FreeSurfer on NIfTI MRI data for research analysis."
- license: MIT License (NeuroClaw custom skill – freely modifiable within the project)
+ description: "Plan or run FreeSurfer recon-all from structural MRI, resume an existing subject, or validate surfaces, segmentations and statistics."
+ license: MIT License (NeuroClaw custom skill)
layer: base
skill_type: tool
dependencies:
- claw-shell
---
# FreeSurfer Tool
- ## Overview
-
- FreeSurfer is the gold-standard open-source suite for automated reconstruction of the brain’s cortical surface from structural MRI, including skull-stripping, intensity normalization, Talairach registration, cortical parcellation (Desikan-Killiany / Destrieux atlases), subcortical segmentation (`aseg`), surface mesh generation, cortical thickness estimation, and statistics.
-
- This skill serves as the **NeuroClaw interface-layer wrapper** for FreeSurfer and strictly follows the hierarchical design:
-
- 1. Check whether FreeSurfer is installed (`recon-all --version`, `$FREESURFER_HOME` environment variable).
- 2. If not found → immediately invoke `dependency-planner` to plan and (after user confirmation) install the latest stable FreeSurfer release + license setup.
- 3. Collect and confirm: input NIfTI file(s), subject ID, output `SUBJECTS_DIR`, desired stages/flags (e.g. `-all`, `-autorecon1..3`, `-T2`, `-FLAIR`, `-parallel`).
- 4. Generate a clear, numbered execution plan including exact shell commands.
- 5. Present plan, estimated runtime, disk/RAM requirements, and risks → wait for explicit user confirmation (“YES” / “execute” / “proceed”).
- 6. On confirmation → delegate **all** shell command execution to the `claw-shell` skill (environment setup, `recon-all` invocation, logging, progress monitoring).
- 7. Report completion status, log location, output directory, and next steps.
-
- **Key design principle (2026 update)**: No direct `subprocess.run()` calls for long-running FreeSurfer commands. All shell execution is routed through `claw-shell` for centralized logging, timeout handling, real-time output streaming, and interruption safety.
-
- **Research use only.**
-
- ## Quick Reference (Common Use Cases)
-
- | Task | Recommended `recon-all` flags / approach |
- |-----------------------------------|-------------------------------------------------------------------|
- | Full pipeline (most common) | `-all` |
- | Fast subcortical + basic surfaces | `-autorecon1 -autorecon2 -autorecon3` |
- | Cortical surfaces & parcellation | `-autorecon2 -autorecon3` (after `autorecon1` completed) |
- | Improve pial surface with T2 | `-T2 T2w.nii.gz` |
- | Use FLAIR for better segmentation | `-FLAIR FLAIR.nii.gz` |
- | Enable multi-core acceleration | `-parallel -openmp 8` (or match available cores) |
- | Resume interrupted run | Omit `-i` and `-all`, specify stages only |
- | Generate statistics only | `-stats` |
-
- ## Installation Check & Setup
-
- Installation is **fully delegated** to `dependency-planner`.
-
- When FreeSurfer is not detected:
- - Call `dependency-planner` with request:
- "Install latest stable FreeSurfer (8.1.0 or newer) on current OS, including license.txt setup"
- - After user confirms the installation plan → `dependency-planner` handles download, package install, license placement
- - This skill then verifies `$FREESURFER_HOME` and `recon-all` availability
+ Choose the reconstruction stage requested by the user. Preserve provided image,
+ subject and output paths. This document supplies methods; loading it does not
+ execute reconstruction, install a license, delegate work or invoke verification.
- **Prerequisites**:
- - `dependency-planner` (mandatory for installation)
- - `claw-shell` (mandatory for command execution)
- - Valid FreeSurfer academic license (free registration required)
- - ≥16 GB RAM recommended (32 GB+ strongly preferred for `-all`)
+ ## Inputs and environment
- ## Agent Reference Rule
+ For a new full subject, require the actual local T1w image. Optional T2w or FLAIR
+ must exist when supplied; report an invalid optional path rather than silently
+ ignoring it. Do not replace unavailable anatomy with examples or synthetic data.
+ Check the FreeSurfer installation, setup script and license before execution.
+ Run environment setup and the command in the same shell/process environment.
+ Use an available shell executor, including `claw-shell` when exposed; when asked
+ for code, give a runnable external command rather than an unresolved tool call.
- When the agent needs FreeSurfer processing implementation code, it should first consult the curated snippet in `skills/freesurfer-tool/scripts/` instead of copying from the embedded wrapper below.
+ ## New subject versus continuation
- Reference snippet available:
- - `scripts/freesurfer_processor.py` -> recon-all pipeline orchestration: environment setup, stage selection, parallel flags, claw-shell delegation
+ For an unused subject directory, initialize and run the complete workflow:
- Example:
```bash
- python skills/freesurfer-tool/scripts/freesurfer_processor.py \
- --input-mri sub-001_T1w.nii.gz \
- --subjid sub-001 \
- --subjects-dir /data/freesurfer_output \
- --stages all \
- --extra-flags "-T2 T2.nii.gz -parallel -openmp 12"
- ```
-
- ## NeuroClaw recommended wrapper script
-
- ```python
- # freesurfer_processor.py
- import argparse
- import os
- import sys
- from pathlib import Path
- from datetime import datetime
-
- # In real NeuroClaw: these would be agent tool calls
- def check_freesurfer_installed():
- # Simulate check via claw-shell
- # Real impl: call claw-shell with "recon-all --version"
- return False, "FreeSurfer not found (simulation mode)"
-
- def delegate_to_claw_shell(commands, purpose, log_tag):
- print(f"[Delegating to claw-shell] Purpose: {purpose}")
- print(f"Log tag: {log_tag}")
- print("Commands to execute:")
- for cmd in commands:
- print(" " + cmd)
- # Real implementation: agent/tool call to claw-shell
- # e.g. tool_call("claw-shell", commands=commands, log_tag=log_tag, capture_output=True, timeout="24h")
-
- def main():
- parser = argparse.ArgumentParser(description="NeuroClaw FreeSurfer Processor")
- parser.add_argument("--input-mri", required=True, help="Path to T1w (or other) NIfTI file")
- parser.add_argument("--subjid", required=True, help="Subject ID (e.g. sub-001)")
- parser.add_argument("--subjects-dir", required=True, help="Output SUBJECTS_DIR path")
- parser.add_argument("--stages", default="all", help="all / autorecon1 / autorecon2 / autorecon3 / stats / comma-separated stages")
- parser.add_argument("--extra-flags", default="", help="Additional flags, e.g. '-T2 T2.nii.gz -FLAIR FLAIR.nii.gz -parallel -openmp 12'")
- parser.add_argument("--plan-only", action="store_true", help="Show plan without execution")
- args = parser.parse_args()
-
- installed, version_info = check_freesurfer_installed()
- if not installed:
- print("FreeSurfer not detected on system.")
- print("→ Invoking dependency-planner to install FreeSurfer and set up license.")
- print("Please complete the dependency-planner confirmation flow first.")
- sys.exit(1)
-
- print("FreeSurfer detected:", version_info)
-
- subjects_dir = Path(args.subjects_dir).resolve()
- print(f"\nProcessing plan for subject: {args.subjid}")
- print(f"Input MRI : {args.input_mri}")
- print(f"Output dir : {subjects_dir}")
- print(f"Stages : {args.stages}")
- if args.extra_flags:
- print(f"Extra flags : {args.extra_flags}")
-
- # Build shell commands
- commands = []
- # 1. Set environment
- fs_home = "/usr/local/freesurfer" # typical default; adjust if needed
- commands.append(f"export FREESURFER_HOME={fs_home}")
- commands.append(f"source $FREESURFER_HOME/SetUpFreeSurfer.sh")
-
- # 2. recon-all command
- recon_cmd = [
- "recon-all",
- "-subjid", args.subjid,
- "-i", args.input_mri
- ]
-
- if args.stages == "all":
- recon_cmd.append("-all")
- elif "," in args.stages:
- for stage in args.stages.split(","):
- stage = stage.strip()
- if stage:
- recon_cmd.append(f"-{stage}")
- else:
- recon_cmd.append(f"-{args.stages}")
-
- if args.extra_flags:
- recon_cmd.extend(args.extra_flags.split())
-
- # Recommend parallel execution if not disabled
- if "-parallel" not in args.extra_flags and "-openmp" not in args.extra_flags:
- recon_cmd.extend(["-parallel", "-openmp", "8"])
-
- commands.append(" ".join(recon_cmd))
-
- log_tag = f"freesurfer_{args.subjid}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
-
- print("\nExecution plan (to be run via claw-shell):")
- for i, cmd in enumerate(commands, 1):
- print(f"Step {i}: {cmd}")
-
- print(f"\nEstimated runtime: 4–24 hours (full -all), 1–4 hours (segmentation stages only)")
- print(f"Disk usage: ~2–5 GB per subject")
- print(f"Logs will be captured by claw-shell under tag: {log_tag}")
-
- if args.plan_only:
- print("\nPlan-only mode — no execution performed.")
- return
-
- confirm = input("\nExecute now? Type YES to proceed: ").strip().upper()
- if confirm != "YES":
- print("Aborted by user.")
- return
-
- print("\nDelegating pipeline execution to claw-shell skill...")
- delegate_to_claw_shell(
- commands=commands,
- purpose=f"FreeSurfer processing for subject {args.subjid} ({args.stages})",
- log_tag=log_tag
- )
-
- print(f"→ Execution handed over to claw-shell.")
- print(f"→ Check logs using tag: {log_tag}")
- print(f"→ Final outputs will be in: {subjects_dir / args.subjid}")
-
- if __name__ == "__main__":
- main()
+ export SUBJECTS_DIR="$OUT/subjects"
+ source "$FREESURFER_HOME/SetUpFreeSurfer.sh"
+ mkdir -p "$SUBJECTS_DIR"
+ recon-all -sd "$SUBJECTS_DIR" -s "$SUBJECT" -i "$T1W" -all
```
- ## Important Notes & Limitations
-
- - All actual shell command execution is delegated to `claw-shell` (no direct `subprocess` calls for `recon-all`).
- - Full `-all` pipeline is very long-running → `claw-shell` should support background/detached mode or long timeouts.
- - Input must be NIfTI (`.nii` or `.nii.gz`); convert DICOM first using `dcm2nii` skill.
- - Output follows standard FreeSurfer structure: `$SUBJECTS_DIR/<subjid>`.
- - Windows users: strongly recommended to use WSL2 (installation handled by `dependency-planner`).
- - License check: skill assumes `license.txt` is already in place after `dependency-planner` run.
-
- ## When to Call This Skill
-
- - User provides structural MRI (NIfTI) and wants automated FreeSurfer processing.
- - Any mention of `recon-all`, `aseg`, `aparc`, cortical thickness, surface reconstruction, or FreeSurfer statistics.
-
- ## Complementary / Related Skills
-
- - `dependency-planner` → install FreeSurfer + license
- - `claw-shell` → safe execution of long-running shell commands
- - `conda-env-manager` → manage Python environment for post-processing FreeSurfer outputs
-
- ## Reference
-
- Official site: https://surfer.nmr.mgh.harvard.edu
- Latest stable release (as of 2026): FreeSurfer 8.1.0 or newer
- License registration: https://surfer.nmr.mgh.harvard.edu/registration.html
- Documentation: https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferWiki
-
- Custom NeuroClaw skill created to integrate FreeSurfer safely into the hierarchical skill structure.
-
- Curated reference snippet in this skill:
- - `skills/freesurfer-tool/scripts/freesurfer_processor.py`
-
- ## Post-Execution Verification (Harness Integration)
-
- After FreeSurfer processing completes, this skill **automatically invokes harness-core's VerificationRunner** to validate output integrity:
-
- **Integrated verification checks**:
-
- ```python
- from skills.harness_core import VerificationRunner, AuditLogger
-
- verifier = VerificationRunner(task_type="freesurfer_processing")
+ The variables represent user-selected paths. Quote them and validate the subject
+ identifier. A new import uses `-i`; continuation of an existing initialized
+ subject uses its existing MRI inputs and omits `-i`. Do not silently overwrite
+ or import again because a completion marker is absent. A marker must be checked
+ alongside the actual exit status, inputs and required outputs.
- # 1. Brain-extracted anatomy files
- verifier.add_check("brain_extraction",
- checker=lambda: verify_brain_extraction(subjects_dir, subjid),
- severity="error"
- )
+ For pial refinement choose **one** available modality: `-T2 "$T2W" -T2pial`,
+ or `-FLAIR "$FLAIR" -FLAIRpial`. If both are supplied, state the chosen modality
+ or request the clinically relevant preference; do not enable both pial modes
+ without verifying version-specific support. Passing `-FLAIR` alone does not
+ request FLAIR pial refinement. For an already processed subject needing only
+ refinement, choose the appropriate continuation stages such as `-autorecon3`.
+ [recon-all reference](https://surfer.nmr.mgh.harvard.edu/fswiki/recon-all).
- # 2. Cortical surface files (white, pial)
- verifier.add_check("surface_reconstruction",
- checker=lambda: verify_surface_files(subjects_dir, subjid),
- severity="error"
- )
+ ## Long jobs and results
- # 3. Cortical thickness bounds (1–4 mm range)
- verifier.add_check("thickness_bounds",
- checker=lambda: verify_cortical_thickness_range(subjects_dir, subjid),
- severity="warning"
- )
+ Foreground code can wait for recon-all and preserve its return code. A detached
+ wrapper must persist PID, command, inputs, stdout/stderr log and terminal exit
+ status. Launch success is a running state. Only mark completion after the process
+ finishes successfully and the required artifacts pass checks. Do not conceal
+ failed child processes with `wait ... || true`.
- # 4. parcellation labels (aparc/aseg)
- verifier.add_check("parcellation",
- checker=lambda: verify_aparc_aseg(subjects_dir, subjid),
- severity="error"
- )
+ Under `$SUBJECTS_DIR/$SUBJECT`, check the files required by the requested stage:
- # 5. Statistics file completeness
- verifier.add_check("statistics",
- checker=lambda: verify_stats_files(subjects_dir, subjid),
- severity="warning"
- )
+ | Output | Relative location |
+ |---|---|
+ | Segmentation | `mri/aseg.mgz`, `mri/aparc+aseg.mgz` |
+ | White/pial surfaces | `surf/lh.white`, `surf/rh.white`, `surf/lh.pial`, `surf/rh.pial` |
+ | Thickness | `surf/lh.thickness`, `surf/rh.thickness` |
+ | Cortical annotations | `label/lh.aparc.annot`, `label/rh.aparc.annot` |
+ | Statistics | `stats/aseg.stats`, `stats/lh.aparc.stats`, `stats/rh.aparc.stats` |
+ | Native logs/status | `scripts/recon-all.log`, `scripts/recon-all.done` |
- report = verifier.run(subjects_dir)
+ Build paths with their directory prefixes; the names alone are not relative to
+ the subject root. Use a JSON serializer for summaries containing paths and logs.
+ Report missing, running, failed and verified outcomes separately. Image/surface
+ quality needs content review beyond file existence; a single thickness range is
+ not a universal pass criterion. [Output-file reference](https://surfer.nmr.mgh.harvard.edu/fswiki/ReconAllOutputFiles).
- # Log verification results
- logger = AuditLogger(log_file=f"{subjects_dir}/{subjid}/freesurfer_verification.jsonl")
- logger.log_validation(
- task_name="freesurfer_processing",
- subject_id=subjid,
- checks_passed=len([r for r in report.results if r.passed]),
- total_checks=len(report.results)
- )
- ```
+ ## Repository adapters
- **Output**: `{SUBJECTS_DIR}/{subjid}/freesurfer_verification.jsonl` (structured audit log with JSONL format)
+ `scripts/freesurfer_processor.py` is a historical adapter/example. Inspect its
+ implementation before choosing it as an executor. A helper that prints commands
+ or returns a fixed installation status is illustrative, not an executed handoff.
+ Likewise, verification requires actual implemented checks and an explicit caller;
+ there is no automatic `VerificationRunner` call when this document is read.
- ---
+ For installation use the [official installation guide](https://surfer.nmr.mgh.harvard.edu/fswiki/DownloadAndInstall)
+ and the installed version's help. Do not assume a latest version or local path.
- Created At: 2026-03-19 20:00 HKT
- Last Updated At: 2026-04-05 02:03 HKT
- Author: chengwang96