Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

utils

utils

Cross-cutting utilities used across the nltools package.

Attributes:

NameTypeDescription
RESERVED_PREFIXPrefix marking a column name generated by nltools rather than the user.

Methods:

NameDescription
all_sameCheck if all items in a sequence are equal to the first item.
attempt_to_importAttempt to import an optional dependency, returning None if unavailable.
coalesced_gcCollapse nilearn’s forced per-copy gc.collect() calls into ONE per operation.
concatenateConcatenate a list of BrainData() or Adjacency() objects.
get_resource_pathGet path to nltools resource directory.
is_reserved_nameReturn True if name is in the nltools-generated column namespace.
make_progress_barBuild a progress bar, or a no-op stand-in when progress_bar is False.
maybe_tqdmWrap iterable in a tqdm progress bar only when progress_bar is True.
reserved_nameBuild a generated column name inside the reserved namespace.
run_separated_nameBuild the run-separated variant of a column name.

Methods

all_same

all_same(items)

Check if all items in a sequence are equal to the first item.

Parameters:

NameTypeDescriptionDefault
itemsA sequence of items to compare.required

Returns:

NameTypeDescription
boolTrue if all items equal the first item, False otherwise.

Examples:

>>> all_same([1, 1, 1])
True
>>> all_same([1, 2, 1])
False

attempt_to_import

attempt_to_import(dependency, name = None, fromlist = None)

Attempt to import an optional dependency, returning None if unavailable.

This function is used to handle optional dependencies gracefully. If the import fails, the function returns None rather than raising an error, allowing the calling code to check and handle missing dependencies.

Parameters:

NameTypeDescriptionDefault
dependencyThe module name to import (e.g., ‘torch’, ‘cupy’).required
nameOptional name to store the dependency under in module_names. Defaults to the dependency name.None
fromlistOptional list of names to import from the module.None

Returns:

TypeDescription
The imported module, or None if the import failed.

Examples:

>>> torch = attempt_to_import('torch')
>>> if torch is not None:
...     # Use torch
...     pass

coalesced_gc

coalesced_gc()

Collapse nilearn’s forced per-copy gc.collect() calls into ONE per operation.

nilearn calls gc.collect() after every masked-array copy (_utils/niimg.py:safe_get_data); a masking-heavy op — a GLM fit that re-validates the same mask and builds several result maps — fires dozens. With torch/nilearn/sklearn resident each sweep costs ~0.1s, so the storm dominates the wall-clock of otherwise-trivial numerical work.

This no-ops the interim collects and runs a single real collect on exit, so peak memory stays bounded to one operation’s worth of cyclic garbage (the gc.collect() nilearn calls is a peak-memory optimization, not a correctness requirement — suppressing it only defers reclamation). Opt out with NLTOOLS_NO_GC_COALESCE=1.

Because @contextmanager results double as decorators, this can also be used as @coalesced_gc() on an operation-boundary method.

Nesting is safe: each frame restores whatever it saved, so only the outermost frame restores the real gc.collect and runs the final sweep; inner frames’ exit-time collect is a no-op.

Caveat: this swaps a process-global builtin. It is safe under the default loky (process) worker backend — each worker has its own gc. Under a threading backend there is a brief window where a concurrent thread sees the no-op collect; NLTOOLS_NO_GC_COALESCE=1 is the escape hatch there.

concatenate

concatenate(data)

Concatenate a list of BrainData() or Adjacency() objects.

get_resource_path

get_resource_path()

Get path to nltools resource directory.

is_reserved_name

is_reserved_name(name: str) -> bool

Return True if name is in the nltools-generated column namespace.

make_progress_bar

make_progress_bar(*, progress_bar: bool, **tqdm_kwargs: bool)

Build a progress bar, or a no-op stand-in when progress_bar is False.

Use this for call sites that drive the bar manually via .update() rather than by iteration. Uses tqdm.auto, so notebooks get widget bars and terminals get text bars.

Parameters:

NameTypeDescriptionDefault
progress_barboolWhether to display a progress bar.required
**tqdm_kwargsForwarded to tqdm (e.g. total, desc, unit).{}

Returns:

TypeDescription
A tqdm instance, or a _NullProgressBar exposing the same subset of
its interface (update, close, set_postfix, set_description, and
the context-manager protocol).

maybe_tqdm

maybe_tqdm(iterable, *, progress_bar: bool, **tqdm_kwargs: bool)

Wrap iterable in a tqdm progress bar only when progress_bar is True.

tqdm writes to stderr, so an unconditional bar makes functions noisy when called in a loop (a 100-iteration calibration study would emit 100 bars). Importing tqdm lazily also keeps it off the import path when unused. Uses tqdm.auto, so notebooks get widget bars and terminals get text bars.

Parameters:

NameTypeDescriptionDefault
iterableThe iterable to wrap.required
progress_barboolWhether to display a progress bar.required
**tqdm_kwargsForwarded to tqdm (e.g. desc, unit, total).{}

Returns:

TypeDescription
The original iterable, or a tqdm-wrapped version of it.

Examples:

for i in maybe_tqdm(range(n_permute), progress_bar=progress_bar,
                    desc="CPU parallel perms", unit="perm"):
    ...

reserved_name

reserved_name(base: str) -> str

Build a generated column name inside the reserved namespace.

Parameters:

NameTypeDescriptionDefault
basestrName without the reserved prefix, e.g. 'poly_0'.required

Returns:

NameTypeDescription
strstrbase prefixed with RESERVED_PREFIX, idempotently — a name
strthat already carries the prefix is returned unchanged.

run_separated_name

run_separated_name(run_idx: int, name: str) -> str

Build the run-separated variant of a column name.

Run separation is an nltools-generated naming decision, so the result always lands in the reserved namespace regardless of whether the source column was user-named (motion_x.nl_r0_motion_x) or already generated (.nl_poly_0.nl_r0_poly_0; prefixes never stack).

Parameters:

NameTypeDescriptionDefault
run_idxintZero-based run index.required
namestrColumn name to separate.required

Returns:

NameTypeDescription
strstr.nl_r{run_idx}_{base}.