freesurfer-tool · diff
git:20260505.e9ddd22 to git:20260506.86420c0
1 added, 1 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)
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
**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`)
## Agent Reference Rule
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.
Reference snippet available:
- `scripts/freesurfer_processor.py` -> recon-all pipeline orchestration: environment setup, stage selection, parallel flags, claw-shell delegation
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()
```
## 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 & Source
+ ## 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")
# 1. Brain-extracted anatomy files
verifier.add_check("brain_extraction",
checker=lambda: verify_brain_extraction(subjects_dir, subjid),
severity="error"
)
# 2. Cortical surface files (white, pial)
verifier.add_check("surface_reconstruction",
checker=lambda: verify_surface_files(subjects_dir, subjid),
severity="error"
)
# 3. Cortical thickness bounds (1–4 mm range)
verifier.add_check("thickness_bounds",
checker=lambda: verify_cortical_thickness_range(subjects_dir, subjid),
severity="warning"
)
# 4. parcellation labels (aparc/aseg)
verifier.add_check("parcellation",
checker=lambda: verify_aparc_aseg(subjects_dir, subjid),
severity="error"
)
# 5. Statistics file completeness
verifier.add_check("statistics",
checker=lambda: verify_stats_files(subjects_dir, subjid),
severity="warning"
)
report = verifier.run(subjects_dir)
# 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)
)
```
**Output**: `{SUBJECTS_DIR}/{subjid}/freesurfer_verification.jsonl` (structured audit log with JSONL format)
---
Created At: 2026-03-19 20:00 HKT
Last Updated At: 2026-04-05 02:03 HKT
Author: chengwang96