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.1.tar.gz (24.1 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.1-py3-none-any.whl (26.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for nifti_finder-2.0.1.tar.gz
Algorithm Hash digest
SHA256 dc417ab8d4c36a9b7a6457134b7236e289cfd984c64f6c2ee3cb48b7bf173101
MD5 d24e3eceb83559e6075ac7913d00e551
BLAKE2b-256 ce9c987435034deb5fb40bab771771fd366091e18309f97666a6a9aae35094f8

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for nifti_finder-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 abc65091ccd5cf40d176ec3a6e82d42ccbc1fe6601807ac0c3c8877c06a95092
MD5 495d107c2f384c10062e14d6c19a792a
BLAKE2b-256 e6c71f28ff1077c76bb406951d75f60e9a22b8c4db31dcc1ba4194343cfba892

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