Skip to main content

Flexible file explorers and filters for navigating neuroimaging datasets and beyond.

Project description

PyPI version Python versions License CI

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 import FileFinder

from your_package import preprocess

# Default: finds all .nii and .nii.gz files (flat recursive scan)
finder = FileFinder()

for path in finder.scan("/path/to/dataset"):
    preprocess(path)

Track subject-level progress in BIDS-style datasets

finder = FileFinder(
    levels={"subjects": "sub-*"},       # directory levels (progress tracks the first)
    patterns="**/anat/*T1w.nii*",        # file patterns at the final stage
)

for path in finder.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

finder = FileFinder(
    levels={"subjects": "sub-*"},
    patterns="**/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 finder.scan("/path/to/dataset"):
    preprocess(path)

API Overview

  • Recommended
    • FileFinder — nested or flat file discovery with levels, patterns, filters, and materialization helpers.
  • Primitives
    • RecursiveFileExplorer — flat recursive glob.
    • NestedFileExplorer — multi-level directory traversal with optional progress; uses patterns at the final stage.
  • Deprecated (removed in v2.2.0)
    • NeuroExplorer — legacy outer / inner two-stage API.
    • AllPurposeFileExplorer, BasicFileExplorer, TwoStageFileExplorer.
  • Filters
    • Include/Exclude: Extension, FilePrefix, FileSuffix, FileRegex, DirectoryPrefix/Suffix/Regex, IfFileExists
    • Filters can be combined with logical operators (AND/OR).
  • Mixins & Interfaces
    • MaterializeMixin — utilities to list, deduplicate, sort, batch, or count matches.
    • FilterableMixin — add, remove, and compose filters dynamically.

Extended Examples

Multi-level directory traversal

finder = FileFinder(
    levels={
        "datasets": "OpenNeuro-ds*",
        "subjects": "sub-*",
        "sessions": "ses-*",
        "anat": "anat",
    },
    patterns=["*_T1w.nii*", "*_FLAIR.nii*"],
)

for path in finder.scan("/path/to/datasets", progress=True, desc="Datasets"):
    preprocess(path)

Use with non-NIfTI files (e.g., JSON)

finder = FileFinder(
    levels={"subjects": "sub-*"},
    patterns="**/*.json",
)
for p in finder.scan("/path/to/bids", progress=True, desc="Subjects"):
    print(p)

Explorers support multiple patterns and filters, but will traverse once per pattern.

Materialize results

FileFinder provides 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
finder = FileFinder(
    levels={"subjects": "sub-*"},
    patterns="**/anat/*T1w.nii*",
)
paths = finder.list("/path/to/dataset", sort=True, unique=True)

Chainable filtering

FileFinder allows include/exclude filters to refine results.

from nifti_finder.filters import IncludeExtension, ExcludeDirPrefix

finder = FileFinder(
    patterns="**/*.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 finder.scan("/path/to/dataset"):
    preprocess(path)

Filters can be dynamically adjusted.

finder.add_filters(ExcludeFileSuffix("mask"))
finder.remove_filters(ExcludeFileSuffix("mask"))
finder.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"
)
finder.add_filters(filename_filter)

Migrating from v1.x

v1.x v2.0
NeuroExplorer() FileFinder() (flat scan; no progress bar)
NeuroExplorer(outer="sub-*", inner="**/*.nii*") FileFinder(levels={"subjects": "sub-*"}, patterns="**/*.nii*")
AllPurposeFileExplorer(pattern="*.json") FileFinder(patterns="*.json")
pattern= patterns=

Legacy shims (NeuroExplorer, AllPurposeFileExplorer, etc.) remain available until v2.2.0.

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

nifti_finder-2.0.0.tar.gz (23.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nifti_finder-2.0.0-py3-none-any.whl (26.1 kB view details)

Uploaded Python 3

File details

Details for the file nifti_finder-2.0.0.tar.gz.

File metadata

  • Download URL: nifti_finder-2.0.0.tar.gz
  • Upload date:
  • Size: 23.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nifti_finder-2.0.0.tar.gz
Algorithm Hash digest
SHA256 98d3e4375fd28e50cc557be90141fcfaf424dcdf33a0d8ea5e882a21a1edccd1
MD5 450c8695dd6614a9c84f03bd1eb072ac
BLAKE2b-256 5210d858176210b3993c35cd773fbcde2d9c27e12aafb0112993b11063ba050b

See more details on using hashes here.

File details

Details for the file nifti_finder-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: nifti_finder-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 26.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nifti_finder-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 207ffb65f698d571ee5ac8646365543fb7faf2db4ad174bfb179e5530238fb13
MD5 1b9fb8e16e00dc115a87480d47caac80
BLAKE2b-256 2afe7b0b1ed20871028d1328101b821f02d14acfd846202f6eed8acfede76b26

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page