roi_spec
tit.opt.roi_spec ¶
Pure-Python ROI-spec resolution for flex-search targets.
Extracted from the former PyQt RoiPickerWidget (as of the v3 audit): the
parts of that widget that turn a
selection (an atlas display name + region names, a volume atlas path +
integer labels, or explicit sphere centers/radii) into one of
:class:tit.opt.config.FlexConfig's nested ROI dataclasses
(SphericalROI, AtlasROI, SubcorticalROI), plus the LUT/label
name resolution the widget uses to show human-readable region names.
Nothing here imports PyQt. Every function takes plain values (subject id,
project dir, atlas/region names, coordinates) instead of reading Qt widget
state, so it is reusable from :mod:tit.server.routes.plan, notebooks, and
future non-Qt UIs alike.
Public API¶
get_roi_spec
Build a SphericalROI / AtlasROI / SubcorticalROI instance
from plain parameters.
resolve_cortical_region_index_map
(hemisphere, region_name) -> annot label index for one atlas.
resolve_atlas_name_for_subject
Subject-prefixed atlas base name ("{subject_id}_{atlas_display}").
resolve_volume_atlas_path
Absolute path to a volumetric atlas file from its display name/space.
resolve_volume_label_names
label_id -> region name for a volumetric atlas, via its sidecar
LUT (or, absent one, the bundled FreeSurfer colour table).
See Also¶
tit.atlas.mesh.MeshAtlasManager : Cortical (.annot) atlas discovery. tit.atlas.voxel.VoxelAtlasManager : Volumetric atlas discovery. tit.opt.config.FlexConfig : Owner of the three nested ROI dataclasses this module builds.
parse_region_names ¶
Parse a comma-separated list of hemisphere-prefixed region names.
Parameters¶
text : str
E.g. "lh.precentral, rh.superiorfrontal".
Returns¶
list of (str, str)
(hemisphere, region_name) tuples, hemisphere lowercased.
Raises¶
ValueError
If any non-empty token is not "<lh|rh>.<name>".
Source code in tit/opt/roi_spec.py
resolve_atlas_name_for_subject ¶
Convert an atlas display name to the subject-specific atlas base name.
The display name is already the atlas type (e.g. "DK40",
"HCP_MMP1") because :meth:MeshAtlasManager.find_all_atlases strips
the subject prefix; this just prepends the target subject id, mirroring
RoiPickerWidget._resolve_atlas_name_for_subject.
Source code in tit/opt/roi_spec.py
resolve_cortical_region_index_map ¶
Map (hemisphere, region_name) -> annot label index for one atlas.
Parameters¶
seg_dir : str
m2m_{subject}/segmentation/ directory.
atlas_display : str
Atlas display name as returned by
:meth:MeshAtlasManager.find_all_atlases (e.g. "DK40").
Returns¶
dict
Empty when the atlas's .annot files cannot be read (e.g. no
segmentation for this subject yet).
Source code in tit/opt/roi_spec.py
build_cortical_atlas_roi ¶
build_cortical_atlas_roi(*, subject_id: str, seg_dir: str, atlas_display: str, regions: list[tuple[str, str]], roi_cls: type = FlexConfig) -> Any
Build an AtlasROI from hemisphere-prefixed cortical region names.
Parameters¶
subject_id : str
Subject identifier (no sub- prefix).
seg_dir : str
m2m_{subject}/segmentation/ directory.
atlas_display : str
Atlas display name (e.g. "DK40").
regions : list of (str, str)
(hemisphere, region_name) tuples, as returned by
:func:parse_region_names.
roi_cls : type, optional
The config class owning the AtlasROI dataclass to build.
Defaults to :class:~tit.opt.config.FlexConfig.
Returns¶
roi_cls.AtlasROI
A union across every resolved region (parallel atlas_path /
hemisphere / label lists), scalar-collapsed for a single
region.
Raises¶
ValueError If none of regions resolve to a known annotation label.
Source code in tit/opt/roi_spec.py
resolve_volume_atlas_path ¶
resolve_volume_atlas_path(*, subject_id: str, seg_dir: str, freesurfer_mri_dir: str = '', atlas_filename: str, atlas_space: str, fastsurfer_mri_dir: str = '') -> str
Resolve a volumetric atlas display name/space to an absolute path.
Mirrors RoiPickerWidget._selected_volume_atlas_path for the cases
that do not already carry a full path (e.g. from
:meth:tit.atlas.voxel.VoxelAtlasManager.list_atlases, which returns
(display_name, path) pairs directly -- pass path straight
through in that case, this helper is only needed for a bare filename).
Parameters¶
subject_id : str
Subject identifier.
seg_dir : str
m2m_{subject}/segmentation/ directory (for labeling.nii.gz).
freesurfer_mri_dir : str, optional
Legacy FreeSurfer mri/ directory (recon-all volume atlases).
atlas_filename : str
Bare atlas filename (e.g. "aparc.DKTatlas+aseg.deep.mgz").
atlas_space : str
"subject" or "mni".
fastsurfer_mri_dir : str, optional
FastSurfer mri/ directory. Searched before freesurfer_mri_dir,
matching :meth:tit.atlas.voxel.VoxelAtlasManager.list_atlases.
Source code in tit/opt/roi_spec.py
build_subcortical_roi ¶
build_subcortical_roi(*, atlas_path: str, labels: list[int], tissues: str = 'GM', atlas_space: str = 'subject', roi_cls: type = FlexConfig) -> Any
Build a SubcorticalROI from a resolved atlas path and labels.
Parameters¶
atlas_path : str
Absolute path to the volumetric atlas/mask file.
labels : list of int
Integer label(s) within the atlas.
tissues : str, optional
"GM", "WM", or "both".
atlas_space : str, optional
"subject" or "mni".
roi_cls : type, optional
The config class owning the SubcorticalROI dataclass to build.
Source code in tit/opt/roi_spec.py
build_spherical_roi ¶
build_spherical_roi(*, centers: list[tuple[float, float, float]], radii: list[float], use_mni: bool = False, volumetric: bool = False, tissues: str = 'GM', roi_cls: type = FlexConfig) -> Any
Build a SphericalROI from one or more sphere centers/radii.
Source code in tit/opt/roi_spec.py
get_roi_spec ¶
get_roi_spec(roi_type: str, *, subject_id: str, seg_dir: str, freesurfer_mri_dir: str = '', fastsurfer_mri_dir: str = '', roi_cls: type = FlexConfig, centers: list[tuple[float, float, float]] | None = None, radii: list[float] | None = None, use_mni: bool = False, volumetric: bool = False, sphere_tissues: str = 'GM', atlas_display: str | None = None, regions: list[tuple[str, str]] | None = None, volume_atlas_path: str | None = None, volume_atlas_filename: str | None = None, volume_atlas_space: str = 'subject', subcortical_labels: list[int] | None = None, subcortical_tissues: str = 'GM') -> Any
Build the ROI dataclass matching roi_type from plain parameters.
The single entry point mirroring RoiPickerWidget.get_roi_spec, split
into three dispatchable builders (:func:build_spherical_roi,
:func:build_cortical_atlas_roi, :func:build_subcortical_roi) so
callers that already know their ROI type can call the specific builder
directly instead.
Parameters¶
roi_type : str
One of "spherical", "atlas"/"cortical", "subcortical".
subject_id, seg_dir, freesurfer_mri_dir, fastsurfer_mri_dir : str
Subject context (the three directory arguments are unused for the
"spherical" type).
roi_cls : type, optional
The config class owning the ROI dataclasses to build. Defaults to
:class:~tit.opt.config.FlexConfig.
Returns¶
roi_cls.SphericalROI or roi_cls.AtlasROI or roi_cls.SubcorticalROI
Raises¶
ValueError
If roi_type is unknown, or a required parameter for that type is
missing (mirrors the nested dataclasses' own __post_init__
errors where possible).
Source code in tit/opt/roi_spec.py
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 | |
resolve_volume_label_names ¶
Resolve label_id -> region name for a volumetric atlas.
Reads a sidecar LUT when one exists next to atlas_path; otherwise
falls back to the unique nonzero integer labels actually present in the
volume (via nibabel), named from the bundled standard FreeSurfer colour
table. Mirrors RoiPickerWidget._subcortical_id_name_map /
_resolve_volume_label_entries.
Parameters¶
atlas_path : str
Absolute path to the atlas volume (.mgz/.nii/.nii.gz).
atlas_space : str, optional
"subject" or "mni" -- only affects sidecar-LUT discovery.
Returns¶
dict Empty when the atlas cannot be read (e.g. nibabel not installed, or no subject data yet) rather than raising -- callers fall back to showing the bare integer label.