fastsurfer
tit.pre.fastsurfer ¶
FastSurfer --seg_only deep segmentation.
Replaces the FreeSurfer recon-all stage as the source of a voxel-space
cortical+subcortical parcellation (aparc.DKTatlas+aseg). FastSurfer is
Apache-2.0, PyTorch-only, needs no FreeSurfer binaries and no MATLAB runtime,
and its label ids are byte-identical to FreeSurfer's colour table -- so every
existing reader (VoxelAtlasManager, roi_spec, the analyzer) works on
its output unchanged.
Public API¶
fastsurfer_available
Capability probe: is a runnable FastSurfer checkout present?
fastsurfer_home
Resolved FASTSURFER_HOME (env, else /opt/fastsurfer).
run_fastsurfer
Run run_fastsurfer.sh --seg_only for one subject.
Notes¶
Measured on this project's own spike (docs/dev/DECISIONS.md ยง 2026-09-03 (One Docker image and a real development loop),
sub-ernie, Apple M2, 8 threads, CPU only): ~5 min for the segmentation
itself, 4.84 GiB peak RSS, mean Dice 0.922 (14 subcortical) / 0.914
(20 cortical DKT) against real recon-all output on the same subject.
--no_cc is mandatory: without it FastSurfer downloads 81 MB of
corpus-callosum checkpoints the toolbox has no use for, and the CC module
crashed in that spike after the segmentation was already written.
See Also¶
tit.pre.charm : SimNIBS charm head-mesh generation (runs in parallel). tit.pre.structural.run_pipeline : Full preprocessing pipeline. tit.atlas.segstats : The LUT/label-listing code reused for the sidecar.
fastsurfer_home ¶
fastsurfer_home() -> Path
Return the resolved FastSurfer checkout directory.
$FASTSURFER_HOME when set and non-empty, else
:data:DEFAULT_FASTSURFER_HOME. The directory is not required to exist
-- use :func:fastsurfer_available for that.
Source code in tit/pre/fastsurfer.py
fastsurfer_available ¶
fastsurfer_available() -> bool
Return True when a runnable FastSurfer checkout is present.
Capability-probe shape (same contract as the server's other capability probes): filesystem-only, no subprocess, safe to call on any platform.
Source code in tit/pre/fastsurfer.py
resolve_threads ¶
Resolve explicit, environment, or user-wide automatic thread settings.
resolve_device ¶
resolve_device() -> str
Use FastSurfer's runtime hardware detection unless explicitly overridden.
Source code in tit/pre/fastsurfer.py
inference_environment ¶
Enable upstream's required MPS fallback without changing the server env.
write_derived_outputs ¶
write_derived_outputs(mri_dir: Path, *, logger) -> None
Write the NIfTI copy and label sidecar next to FastSurfer's .mgz.
Split out of :func:run_fastsurfer so a project whose segmentation was
produced by an earlier run (or by hand) can be brought up to the layout
the atlas readers expect without re-running the network.
Raises¶
PreprocessError
If mri_dir holds no :data:SEG_FILENAME.
Source code in tit/pre/fastsurfer.py
run_fastsurfer ¶
run_fastsurfer(project_dir: str, subject_id: str, *, logger, runner: CommandRunner | None = None, threads: int | None = None) -> None
Run FastSurfer --seg_only for one subject.
Writes derivatives/fastsurfer/sub-<id>/mri/aparc.DKTatlas+aseg.deep.mgz
plus a .nii.gz copy and a *_labels.txt sidecar, then returns.
Idempotent: an existing segmentation is left alone (only the derived
NIfTI/labels are backfilled if missing).
The input is the raw BIDS T1w, the same image recon-all was
given. Two reasons, both load-bearing: it keeps this stage independent
of charm so the two can run in parallel after DICOM import (the DAG
in :mod:tit.jobs.plans relies on that), and it is the image the
spike's Dice numbers were measured on -- m2m_<id>/T1.nii.gz is
charm's own bias-corrected, re-conformed volume, a different input with
unmeasured effect on the network's output.
Parameters¶
project_dir : str
BIDS project root.
subject_id : str
Subject identifier without the sub- prefix.
logger : logging.Logger
Logger used for progress and streamed command output.
runner : CommandRunner or None, optional
Subprocess runner used to stream output and honour cancellation.
threads : int or None, optional
Thread count for the inference. Defaults to
$TIT_FASTSURFER_THREADS, else the user-wide preference (automatic: the global CPU limit).
Raises¶
PreprocessError
If FastSurfer is not installed, no T1w is found, run_fastsurfer.sh
exits non-zero, or the expected segmentation is missing afterwards.
See Also¶
fastsurfer_available : Probe before offering this step in a UI. tit.pre.charm.run_charm : The other post-import stage (G2a).
Source code in tit/pre/fastsurfer.py
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | |