Flexible file explorers and filters for navigating neuroimaging datasets and beyond.
Project description
nifti-finder
Navigate neuroimaging datasets (and more) using flexible file explorers and filters. Optimized for typical neuroimaging research workflows, including BIDS-structured datasets.
Key features
- Flexible file discovery with glob-based pattern matching for any dataset structure.
- Rich set of composable filters for precise dataset querying (by file extension, prefix/suffix, regex, existence of related files, etc.).
- Extensible design with modular, reusable interfaces for creating custom explorers and filters
Installation
pip install nifti-finder
# or from source
pip install -e .
Quickstart
Get all NIfTI files from any nested dataset
from nifti_finder.explorers import NeuroExplorer
from your_package import preprocess
# Default: finds all .nii and .nii.gz files
explorer = NeuroExplorer()
for path in explorer.scan("/path/to/dataset"):
preprocess(path)
Track subject-level progress in BIDS-style datasets
explorer = NeuroExplorer(
outer="sub-*", # level to compute progress (e.g., root/sub-*/...)
inner="**/anat/*T1w.nii*", # rest (e.g., ses-*/anat/T1w.nii.gz)
)
for path in explorer.scan("/path/to/dataset", progress=True, desc="Subjects"):
preprocess(path)
Output:
Subjects: 50%|███████████████████▌ | 30/60 [00:15<00:15, 2.00 it/s]
Exclude subjects with missing data; e.g., a segmentation mask
from nifti_finder.filters import IncludeIfFileExists
explorer = NeuroExplorer(
outer="sub-*",
inner="**/anat/*T1w.nii*",
filters=[
IncludeIfFileExists(
filename_pattern="*seg*", # require a segmentation mask
search_in="/labels", # in a parallel labels/ tree
mirror_relative_to="/path/to/dataset",
)
],
)
for path in explorer.scan("/path/to/dataset"):
preprocess(path)
API Overview
- Explorers
AllPurposeFileExplorer- general-purpose scanning with patterns + filters.NeuroExplorer- two-stage scanning (outer/inner) with patterns + filters + progress tracking, optimized for neuroimaging workflows.
- Filters
- Include/Exclude:
Extension,FilePrefix,FileSuffix,FileRegex,DirectoryPrefix/Suffix/Regex,IfFileExists - Filters can be combined with logical operators (
AND/OR).
- Include/Exclude:
- Mixins & Interfaces
BasicFileExplorer&TwoStageFileExplorerfor file traversalMaterializeMixin— utilities to list, deduplicate, sort, batch, or count matches.FilterableMixin— add, remove, and compose filters dynamically.
Extended Examples
Use with non-NIfTI files (e.g., JSON)
explorer = NeuroExplorer(outer="sub-*", inner="**/*.json")
for p in explorer.scan("/path/to/bids", progress=True, desc="Subjects"):
print(p)
Explorers support multiple patterns and filters, but will traverse once per pattern.
General-purpose exploration
If you don’t want to assume any nested (subject/... or dataset/subject/...) hierarchy, use AllPurposeFileExplorer for flexible scanning.
from nifti_finder.explorers import AllPurposeFileExplorer
explorer = AllPurposeFileExplorer(pattern="*.json")
for path in explorer.scan("/path/to/dataset"):
print(path)
Materialize results
Both NeuroExplorer and AllPurposeExplorer provide convenience methods to turn the streaming output of scan() into concrete Python data structures.
This is useful when you want:
- A list of paths (with optional sorting, deduplication, or limiting)
- A single path (first match)
- A quick boolean check
- A count
- Iteration in batches
explorer = NeuroExplorer(outer="sub-*", inner="**/anat/*T1w.nii*")
paths = explorer.list("/path/to/dataset", sort=True, unique=True)
Chainable filtering
Both NeuroExplorer and AllPurposeExplorer allow include/exclude filters to refine results.
from nifti_finder.filters import IncludeExtension, ExcludeDirPrefix
explorer = AllPurposeFileExplorer(
pattern="**/*.nii*",
filters=[
ExcludeFileSuffix("preprocessed"), # drop already preprocessed files
ExcludeDirPrefix("bad"), # drop 'bad' files
IncludeIfFileExists(filename_pattern="*mask*"), # keep if a brain mask exists in same directory
],
logic="AND", # combination logic
)
for path in explorer.scan("/path/to/dataset"):
preprocess(path)
Filters can be dynamically adjusted.
explorer.add_filters(ExcludeFileSuffix("mask"))
explorer.remove_filters(ExcludeFileSuffix("mask"))
explorer.clear_filters()
Filters can be composed together to get their own combination logic.
from nifti_finder.filters import ComposeFilter, ExcludeFilePrefix
suffix_filter = ComposeFilter(
filters=[ExcludeFileSuffix("bet"), ExcludeFileSuffix("mask")],
logic="OR"
)
prefix_filter = ComposeFilter(
filters=[ExcludeFileSuffix("pet"), ExcludeFileSuffix("dwi")],
logic="OR"
)
filename_filter = ComposeFilter(
filters=[suffix_filter, prefix_filter],
logic="AND"
)
explorer.add_filters(filename_filter)
Development
# Setup
pip install -e .[test]
# Run tests
pytest -q
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nifti_finder-1.2.0.tar.gz.
File metadata
- Download URL: nifti_finder-1.2.0.tar.gz
- Upload date:
- Size: 22.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fae0f011de8042ea0c72de0853fdbbf0e45a35f8a5b045e65136dbbedf9a4cf8
|
|
| MD5 |
0e2f92fca5580169b5373fd0781cc35b
|
|
| BLAKE2b-256 |
05f40889e60d841884a73c9cf9654f4daf01e50a5bdb97decd9db0d714fd1bcf
|
File details
Details for the file nifti_finder-1.2.0-py3-none-any.whl.
File metadata
- Download URL: nifti_finder-1.2.0-py3-none-any.whl
- Upload date:
- Size: 25.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9374afd6a7091f8b449082016f368d794c0d83ffe827d59d4ed07a8f65a477db
|
|
| MD5 |
582e1fbb2a745a5699e380be1b8b924f
|
|
| BLAKE2b-256 |
e554dd07f33e8df83bb011ce00c0c32a6a107d665fd37bb5c7a922473c3a4611
|