utils¶
Cross-cutting utilities used across the nltools package.
Attributes:
| Name | Type | Description |
|---|---|---|
RESERVED_PREFIX | Prefix marking a column name generated by nltools rather than the user. |
Methods:
| Name | Description |
|---|---|
all_same | Check if all items in a sequence are equal to the first item. |
attempt_to_import | Attempt to import an optional dependency, returning None if unavailable. |
coalesced_gc | Collapse nilearn’s forced per-copy gc.collect() calls into ONE per operation. |
concatenate | Concatenate a list of BrainData() or Adjacency() objects. |
get_resource_path | Get path to nltools resource directory. |
is_reserved_name | Return True if name is in the nltools-generated column namespace. |
make_progress_bar | Build a progress bar, or a no-op stand-in when progress_bar is False. |
maybe_tqdm | Wrap iterable in a tqdm progress bar only when progress_bar is True. |
reserved_name | Build a generated column name inside the reserved namespace. |
run_separated_name | Build 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:
| Name | Type | Description | Default |
|---|---|---|---|
items | A sequence of items to compare. | required |
Returns:
| Name | Type | Description |
|---|---|---|
bool | True if all items equal the first item, False otherwise. |
Examples:
>>> all_same([1, 1, 1])
True
>>> all_same([1, 2, 1])
Falseattempt_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:
| Name | Type | Description | Default |
|---|---|---|---|
dependency | The module name to import (e.g., ‘torch’, ‘cupy’). | required | |
name | Optional name to store the dependency under in module_names. Defaults to the dependency name. | None | |
fromlist | Optional list of names to import from the module. | None |
Returns:
| Type | Description |
|---|---|
| The imported module, or None if the import failed. |
Examples:
>>> torch = attempt_to_import('torch')
>>> if torch is not None:
... # Use torch
... passcoalesced_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) -> boolReturn 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:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar | bool | Whether to display a progress bar. | required |
**tqdm_kwargs | Forwarded to tqdm (e.g. total, desc, unit). | {} |
Returns:
| Type | Description |
|---|---|
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:
| Name | Type | Description | Default |
|---|---|---|---|
iterable | The iterable to wrap. | required | |
progress_bar | bool | Whether to display a progress bar. | required |
**tqdm_kwargs | Forwarded to tqdm (e.g. desc, unit, total). | {} |
Returns:
| Type | Description |
|---|---|
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) -> strBuild a generated column name inside the reserved namespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base | str | Name without the reserved prefix, e.g. 'poly_0'. | required |
Returns:
| Name | Type | Description |
|---|---|---|
str | str | base prefixed with RESERVED_PREFIX, idempotently — a name |
str | that already carries the prefix is returned unchanged. |
run_separated_name¶
run_separated_name(run_idx: int, name: str) -> strBuild 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:
| Name | Type | Description | Default |
|---|---|---|---|
run_idx | int | Zero-based run index. | required |
name | str | Column name to separate. | required |
Returns:
| Name | Type | Description |
|---|---|---|
str | str | .nl_r{run_idx}_{base}. |