Skip to content

Commit

Permalink
Moved lsdirs() and is_hidden() from bcoin.py -> __init__.py
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelzwiers committed Sep 18, 2023
1 parent cb8bc83 commit 2b90a77
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 82 deletions.
26 changes: 26 additions & 0 deletions bidscoin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,29 @@ def bidsversion() -> str:
"""

return (schemafolder/'BIDS_VERSION').read_text().strip()


def is_hidden(path: Path) -> bool:
"""
Checks if a path is or contains a hidden rootfolder.
:param path: The path to be checked
:return: True if a part of the path starts with a '.', otherwise False
"""

if any([p.startswith('.') for p in path.parts]):
return True
else:
return False


def lsdirs(folder: Path, wildcard: str='*') -> List[Path]:
"""
Gets all directories in a folder, ignores files
:param folder: The full pathname of the folder
:param wildcard: Simple (glob.glob) shell-style wildcards. Foldernames starting with a dot are considered hidden and will be skipped. Use '**/wildcard for recursive search'
:return: A list with all directories in the folder
"""

return sorted([fname for fname in sorted(folder.glob(wildcard)) if fname.is_dir() and not is_hidden(fname.relative_to(folder))])
27 changes: 0 additions & 27 deletions bidscoin/bcoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,33 +176,6 @@ def run_command(command: str) -> int:
return process.returncode


def is_hidden(path: Path) -> bool:
"""
Checks if a path contains a hidden folder.
:param path: The path to be checked.
:return: True if a part of the path starts with a '.', otherwise False.
"""

if any([p.name.startswith('.') for p in path.parents]):
LOGGER.verbose(f"Path '{path.absolute()}' is hidden")
return True
else:
return False


def lsdirs(folder: Path, wildcard: str='*') -> List[Path]:
"""
Gets all directories in a folder, ignores files
:param folder: The full pathname of the folder
:param wildcard: Simple (glob.glob) shell-style wildcards. Foldernames starting with a dot are considered hidden and will be skipped. Use '**/wildcard for recursive search'
:return: A list with all directories in the folder
"""

return sorted([fname for fname in sorted(folder.glob(wildcard)) if fname.is_dir() and not is_hidden(fname.relative_to(folder))])


def list_executables(show: bool=False) -> list:
"""
:param show: Print the installed console scripts if True
Expand Down
34 changes: 16 additions & 18 deletions bidscoin/bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
if find_spec('bidscoin') is None:
import sys
sys.path.append(str(Path(__file__).parents[1]))
from bidscoin import bcoin, schemafolder, heuristicsfolder, bidsmap_template, __version__
from bidscoin import bcoin, schemafolder, heuristicsfolder, bidsmap_template, is_hidden, lsdirs
from bidscoin.utilities import dicomsort
from ruamel.yaml import YAML
yaml = YAML()
Expand Down Expand Up @@ -326,7 +326,7 @@ def unpack(sourcefolder: Path, wildcard: str='', workfolder: Path='') -> Tuple[L
tarzipfiles = list(sourcefolder.glob(wildcard)) if wildcard else []

# See if we have a flat unsorted (DICOM) data organization, i.e. no directories, but DICOM-files
flatDICOM = not bcoin.lsdirs(sourcefolder) and get_dicomfile(sourcefolder).is_file()
flatDICOM = not lsdirs(sourcefolder) and get_dicomfile(sourcefolder).is_file()

# Check if we are going to do unpacking and/or sorting
if tarzipfiles or flatDICOM or (sourcefolder/'DICOMDIR').is_file():
Expand Down Expand Up @@ -385,8 +385,6 @@ def is_dicomfile(file: Path) -> bool:
"""

if file.is_file():
if file.stem.startswith('.'):
LOGGER.verbose(f'File is hidden: {file}')
with file.open('rb') as dicomfile:
dicomfile.seek(0x80, 1)
if dicomfile.read(4) == b'DICM':
Expand Down Expand Up @@ -446,8 +444,8 @@ def get_dicomfile(folder: Path, index: int=0) -> Path:
:return: The filename of the first dicom-file in the folder.
"""

if folder.name.startswith('.'):
LOGGER.verbose(f'Ignoring hidden folder: {folder}')
if is_hidden(folder):
LOGGER.verbose(f"Ignoring hidden folder: {folder}")
return Path()

if (folder/'DICOMDIR').is_file():
Expand All @@ -458,8 +456,8 @@ def get_dicomfile(folder: Path, index: int=0) -> Path:

idx = 0
for file in files:
if file.stem.startswith('.'):
LOGGER.verbose(f'Ignoring hidden file: {file}')
if is_hidden(file):
LOGGER.verbose(f"Ignoring hidden file: {file}")
continue
if is_dicomfile(file):
if idx == index:
Expand All @@ -478,14 +476,14 @@ def get_parfiles(folder: Path) -> List[Path]:
:return: The filenames of the PAR-files in the folder.
"""

if folder.name.startswith('.'):
LOGGER.verbose(f'Ignoring hidden folder: {folder}')
if is_hidden(folder):
LOGGER.verbose(f"Ignoring hidden folder: {folder}")
return []

parfiles = []
for file in sorted(folder.iterdir()):
if file.stem.startswith('.'):
LOGGER.verbose(f'Ignoring hidden file: {file}')
if is_hidden(file):
LOGGER.verbose(f"Ignoring hidden file: {file}")
continue
if is_parfile(file):
parfiles.append(file)
Expand All @@ -498,8 +496,8 @@ def get_datasource(session: Path, plugins: dict, recurse: int=2) -> DataSource:

datasource = DataSource()
for item in sorted(session.iterdir()):
if item.stem.startswith('.'):
LOGGER.verbose(f'Ignoring hidden datasource: {item}')
if is_hidden(item):
LOGGER.verbose(f"Ignoring hidden data-source: {item}")
continue
if item.is_dir() and recurse:
datasource = get_datasource(item, plugins, recurse-1)
Expand Down Expand Up @@ -901,10 +899,10 @@ def load_bidsmap(yamlfile: Path, folder: Path=Path(), plugins:Union[tuple,list]=
bidsmapversion = bidsmap['Options']['version']
else:
bidsmapversion = 'Unknown'
if bidsmapversion.rsplit('.', 1)[0] != __version__.rsplit('.', 1)[0] and any(checks):
LOGGER.warning(f'BIDScoiner version conflict: {yamlfile} was created with version {bidsmapversion}, but this is version {__version__}')
elif bidsmapversion != __version__ and any(checks):
LOGGER.info(f'BIDScoiner version difference: {yamlfile} was created with version {bidsmapversion}, but this is version {__version__}. This is normally ok but check the https://bidscoin.readthedocs.io/en/latest/CHANGELOG.html')
if bidsmapversion.rsplit('.', 1)[0] != bidscoinversion.rsplit('.', 1)[0] and any(checks):
LOGGER.warning(f'BIDScoiner version conflict: {yamlfile} was created with version {bidsmapversion}, but this is version {bidscoinversion}')
elif bidsmapversion != bidscoinversion and any(checks):
LOGGER.info(f'BIDScoiner version difference: {yamlfile} was created with version {bidsmapversion}, but this is version {bidscoinversion}. This is normally ok but check the https://bidscoin.readthedocs.io/en/latest/CHANGELOG.html')

# Make sure we get a proper plugin options and dataformat sections (use plugin default bidsmappings when a template bidsmap is loaded)
if not bidsmap['Options'].get('plugins'):
Expand Down
6 changes: 3 additions & 3 deletions bidscoin/bidsapps/deface.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
if find_spec('bidscoin') is None:
import sys
sys.path.append(str(Path(__file__).parents[2]))
from bidscoin import bcoin, bids
from bidscoin import bcoin, bids, lsdirs


def deface(bidsdir: str, pattern: str, subjects: list, force: bool, output: str, cluster: bool, nativespec: str, kwargs: dict):
Expand Down Expand Up @@ -45,7 +45,7 @@ def deface(bidsdir: str, pattern: str, subjects: list, force: bool, output: str,

# Get the list of subjects
if not subjects:
subjects = bcoin.lsdirs(bidsdir, 'sub-*')
subjects = lsdirs(bidsdir, 'sub-*')
if not subjects:
LOGGER.warning(f"No subjects found in: {bidsdir/'sub-*'}")
else:
Expand All @@ -70,7 +70,7 @@ def deface(bidsdir: str, pattern: str, subjects: list, force: bool, output: str,
for n, subject in enumerate(tqdm(subjects, unit='subject', leave=False), 1):

subid = subject.name
sessions = bcoin.lsdirs(subject, 'ses-*')
sessions = lsdirs(subject, 'ses-*')
if not sessions:
sessions = [subject]
for session in sessions:
Expand Down
6 changes: 3 additions & 3 deletions bidscoin/bidsapps/echocombine.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
if find_spec('bidscoin') is None:
import sys
sys.path.append(str(Path(__file__).parents[2]))
from bidscoin import bcoin, bids
from bidscoin import bcoin, bids, lsdirs

unknowndatatype = 'extra_data'

Expand Down Expand Up @@ -44,7 +44,7 @@ def echocombine(bidsdir: str, pattern: str, subjects: list, output: str, algorit

# Get the list of subjects
if not subjects:
subjects = bcoin.lsdirs(bidsdir, 'sub-*')
subjects = lsdirs(bidsdir, 'sub-*')
if not subjects:
LOGGER.warning(f"No subjects found in: {bidsdir/'sub-*'}")
else:
Expand All @@ -56,7 +56,7 @@ def echocombine(bidsdir: str, pattern: str, subjects: list, output: str, algorit
for n, subject in enumerate(tqdm(subjects, unit='subject', leave=False), 1):

subid = subject.name
sessions = bcoin.lsdirs(subject, 'ses-*')
sessions = lsdirs(subject, 'ses-*')
if not sessions:
sessions = [subject]
for session in sessions:
Expand Down
8 changes: 4 additions & 4 deletions bidscoin/bidsapps/medeface.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
if find_spec('bidscoin') is None:
import sys
sys.path.append(str(Path(__file__).parents[2]))
from bidscoin import bcoin, bids
from bidscoin import bcoin, bids, lsdirs


def medeface(bidsdir: str, pattern: str, maskpattern: str, subjects: list, force: bool, output: str, cluster: bool, nativespec: str, kwargs: dict):
Expand Down Expand Up @@ -51,7 +51,7 @@ def medeface(bidsdir: str, pattern: str, maskpattern: str, subjects: list, force

# Get the list of subjects
if not subjects:
subjects = bcoin.lsdirs(bidsdir, 'sub-*')
subjects = lsdirs(bidsdir, 'sub-*')
if not subjects:
LOGGER.warning(f"No subjects found in: {bidsdir/'sub-*'}")
else:
Expand All @@ -76,7 +76,7 @@ def medeface(bidsdir: str, pattern: str, maskpattern: str, subjects: list, force
for n, subject in enumerate(subjects, 1):

subid = subject.name
sessions = bcoin.lsdirs(subject, 'ses-*')
sessions = lsdirs(subject, 'ses-*')
if not sessions:
sessions = [subject]
for session in sessions:
Expand Down Expand Up @@ -128,7 +128,7 @@ def medeface(bidsdir: str, pattern: str, maskpattern: str, subjects: list, force
for n, subject in enumerate(tqdm(subjects, unit='subject', leave=False), 1):

subid = subject.name
sessions = bcoin.lsdirs(subject, 'ses-*')
sessions = lsdirs(subject, 'ses-*')
if not sessions:
sessions = [subject]
for session in sessions:
Expand Down
6 changes: 3 additions & 3 deletions bidscoin/bidsapps/skullstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
if find_spec('bidscoin') is None:
import sys
sys.path.append(str(Path(__file__).parents[2]))
from bidscoin import bcoin, bids
from bidscoin import bcoin, bids, lsdirs


def skullstrip(bidsdir: str, pattern: str, subjects: list, masked: str, output: list, force: bool, args: str, cluster: bool):
Expand Down Expand Up @@ -56,7 +56,7 @@ def skullstrip(bidsdir: str, pattern: str, subjects: list, masked: str, output:

# Get the list of subjects
if not subjects:
subjects = bcoin.lsdirs(bidsdir, 'sub-*')
subjects = lsdirs(bidsdir, 'sub-*')
if not subjects:
LOGGER.warning(f"No subjects found in: {bidsdir/'sub-*'}")
else:
Expand All @@ -68,7 +68,7 @@ def skullstrip(bidsdir: str, pattern: str, subjects: list, masked: str, output:
for n, subject in enumerate(tqdm(subjects, unit='subject', leave=False), 1):

subid = subject.name
sessions = bcoin.lsdirs(subject, 'ses-*')
sessions = lsdirs(subject, 'ses-*')
if not sessions:
sessions = [subject]
for session in sessions:
Expand Down
6 changes: 3 additions & 3 deletions bidscoin/bidsapps/slicereport.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from importlib.util import find_spec
if find_spec('bidscoin') is None:
sys.path.append(str(Path(__file__).parents[2]))
from bidscoin import bcoin, bids, bidsversion, __version__
from bidscoin import bcoin, bids, lsdirs, bidsversion, __version__

html_head = """<!DOCTYPE html>
<html lang="en">
Expand Down Expand Up @@ -159,7 +159,7 @@ def slicereport(bidsdir: str, pattern: str, outlinepattern: str, outlineimage: s

# Get the list of subjects
if not subjects:
subjects = bcoin.lsdirs(bidsdir, 'sub-*')
subjects = lsdirs(bidsdir, 'sub-*')
if not subjects:
print(f"No subjects found in: {bidsdir/'sub-*'}"); return
else:
Expand All @@ -185,7 +185,7 @@ def slicereport(bidsdir: str, pattern: str, outlinepattern: str, outlineimage: s

# Loop over the subject/session-directories
for subject in subjects:
sessions = bcoin.lsdirs(subject, 'ses-*')
sessions = lsdirs(subject, 'ses-*')
if not sessions:
sessions = [subject]
for session in sessions:
Expand Down
8 changes: 4 additions & 4 deletions bidscoin/bidscoiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
if find_spec('bidscoin') is None:
import sys
sys.path.append(str(Path(__file__).parents[1]))
from bidscoin import bcoin, bids, bidsversion, __version__
from bidscoin import bcoin, bids, lsdirs, bidsversion, __version__


def bidscoiner(rawfolder: str, bidsfolder: str, subjects: list=(), force: bool=False, bidsmapfile: str='bidsmap.yaml') -> None:
Expand Down Expand Up @@ -125,7 +125,7 @@ def bidscoiner(rawfolder: str, bidsfolder: str, subjects: list=(), force: bool=F
subprefix = bidsmap['Options']['bidscoin']['subprefix'].replace('*','')
sesprefix = bidsmap['Options']['bidscoin']['sesprefix'].replace('*','')
if not subjects:
subjects = bcoin.lsdirs(rawfolder, (subprefix if subprefix!='*' else '') + '*')
subjects = lsdirs(rawfolder, (subprefix if subprefix!='*' else '') + '*')
if not subjects:
LOGGER.warning(f"No subjects found in: {rawfolder/subprefix}*")
else:
Expand All @@ -140,7 +140,7 @@ def bidscoiner(rawfolder: str, bidsfolder: str, subjects: list=(), force: bool=F
LOGGER.error(f"The '{subject}' subject folder does not exist")
continue

sessions = bcoin.lsdirs(subject, (sesprefix if sesprefix!='*' else '') + '*')
sessions = lsdirs(subject, (sesprefix if sesprefix!='*' else '') + '*')
if not sessions or (subject/'DICOMDIR').is_file():
sessions = [subject]
for session in sessions:
Expand All @@ -161,7 +161,7 @@ def bidscoiner(rawfolder: str, bidsfolder: str, subjects: list=(), force: bool=F
if not force and bidssession.is_dir():
datatypes = []
for dataformat in dataformats:
for datatype in bcoin.lsdirs(bidssession): # See what datatypes we already have in the bids session-folder
for datatype in lsdirs(bidssession): # See what datatypes we already have in the bids session-folder
if list(datatype.iterdir()) and bidsmap[dataformat].get(datatype.name): # See if we are going to add data for this datatype
datatypes.append(datatype.name)
if datatypes:
Expand Down
6 changes: 3 additions & 3 deletions bidscoin/bidsmapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from importlib.util import find_spec
if find_spec('bidscoin') is None:
sys.path.append(str(Path(__file__).parents[1]))
from bidscoin import bcoin, bids, check_version, __version__
from bidscoin import bcoin, bids, lsdirs, check_version, __version__

_, uptodate, versionmessage = check_version()

Expand Down Expand Up @@ -103,13 +103,13 @@ def bidsmapper(rawfolder: str, bidsfolder: str, bidsmapfile: str, templatefile:
return {}

# Loop over all subjects and sessions and built up the bidsmap entries
subjects = bcoin.lsdirs(rawfolder, ('' if subprefix=='*' else subprefix) + '*')
subjects = lsdirs(rawfolder, ('' if subprefix=='*' else subprefix) + '*')
if not subjects:
LOGGER.warning(f'No subjects found in: {rawfolder/subprefix}*')
with logging_redirect_tqdm():
for n, subject in enumerate(tqdm(subjects, unit='subject', leave=False), 1):

sessions = bcoin.lsdirs(subject, ('' if sesprefix=='*' else sesprefix) + '*')
sessions = lsdirs(subject, ('' if sesprefix=='*' else sesprefix) + '*')
if not sessions or (subject/'DICOMDIR').is_file():
sessions = [subject]
for session in sessions:
Expand Down
6 changes: 3 additions & 3 deletions bidscoin/plugins/dcm2niix2bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from bids_validator import BIDSValidator
from typing import Union
from pathlib import Path
from bidscoin import bcoin, bids
from bidscoin import bcoin, bids, lsdirs
from bidscoin.utilities import physio
try:
from nibabel.testing import data_path
Expand Down Expand Up @@ -120,7 +120,7 @@ def bidsmapper_plugin(session: Path, bidsmap_new: dict, bidsmap_old: dict, templ
# Collect the different DICOM/PAR source files for all runs in the session
sourcefiles = []
if dataformat == 'DICOM':
for sourcedir in bcoin.lsdirs(session, '**/*'):
for sourcedir in lsdirs(session, '**/*'):
for n in range(1): # Option: Use range(2) to scan two files and catch e.g. magnitude1/2 fieldmap files that are stored in one Series folder (but bidscoiner sees only the first file anyhow and it makes bidsmapper 2x slower :-()
sourcefile = bids.get_dicomfile(sourcedir, n)
if sourcefile.name and is_sourcefile(sourcefile):
Expand Down Expand Up @@ -198,7 +198,7 @@ def bidscoiner_plugin(session: Path, bidsmap: dict, bidsses: Path) -> None:
manufacturer = 'UNKNOWN'
sources = []
if dataformat == 'DICOM':
sources = bcoin.lsdirs(session, '**/*')
sources = lsdirs(session, '**/*')
manufacturer = datasource.attributes('Manufacturer')
elif dataformat == 'PAR':
sources = bids.get_parfiles(session)
Expand Down
Loading

0 comments on commit 2b90a77

Please sign in to comment.