fsl.utils.path

This module contains a few utility functions for working with file system paths.

deepest

Finds the deepest directory which ends with one of the given sequence of suffixes, or returns None if no directories end with any of the suffixes.

shallowest

Finds the shallowest directory which ends with one of the given sequence of suffixes, or returns None if no directories end with any of the suffixes.

allFiles

Return a list containing all files which exist underneath the specified root directory.

hasExt

Convenience function which returns True if the given path ends with any of the given allowedExts, False otherwise.

addExt

Adds a file extension to the given file prefix.

removeExt

Returns the base name of the given file name.

getExt

Returns the extension of the given file name.

splitExt

Returns the base name and the extension from the given file name.

getFileGroup

If the given path is part of a fileGroup, returns a list containing the paths to all other files in the group (including the path itself).

removeDuplicates

Reduces the list of paths down to those which are unique with respect to the specified fileGroups.

uniquePrefix

Return the longest prefix for the given file name which unambiguously identifies it, relative to the other files in the same directory.

commonBase

Identifies the deepest common base directory shared by all files in paths.

wslpath

Convert Windows path (or a command line argument containing a Windows path) to the equivalent WSL path (e.g. c:\Users -> /mnt/c/Users).

winpath

Convert a WSL-local filepath (for example /usr/local/fsl/) into a path that can be used from Windows.

exception fsl.utils.path.PathError[source]

Bases: Exception

Exception class raised by the functions defined in this module when something goes wrong.

__annotations__ = {}
__module__ = 'fsl.utils.path'
__weakref__

list of weak references to the object (if defined)

fsl.utils.path.deepest(path, suffixes)[source]

Finds the deepest directory which ends with one of the given sequence of suffixes, or returns None if no directories end with any of the suffixes.

fsl.utils.path.shallowest(path, suffixes)[source]

Finds the shallowest directory which ends with one of the given sequence of suffixes, or returns None if no directories end with any of the suffixes.

fsl.utils.path.allFiles(root)[source]

Return a list containing all files which exist underneath the specified root directory.

fsl.utils.path.hasExt(path: str | Path, allowedExts: Sequence[str]) bool[source]

Convenience function which returns True if the given path ends with any of the given allowedExts, False otherwise.

fsl.utils.path.addExt(prefix: str | Path, allowedExts: Sequence[str] | None = None, mustExist: bool = True, defaultExt: str | None = None, fileGroups: Sequence[Sequence[str]] | None = None, unambiguous: bool = True) Sequence[str] | str[source]

Adds a file extension to the given file prefix.

If mustExist is False, and the file does not already have a supported extension, the default extension is appended and the new file name returned. If the prefix already has a supported extension, it is returned unchanged.

If mustExist is True (the default), the function checks to see if any files exist that have the given prefix, and a supported file extension. A PathError is raised if:

  • No files exist with the given prefix and a supported extension.

  • fileGroups is None and unambiguous is True, and more than one file exists with the given prefix, and a supported extension.

Otherwise the full file name is returned.

Parameters:
  • prefix – The file name prefix to modify.

  • allowedExts – List of allowed file extensions.

  • mustExist – Whether the file must exist or not.

  • defaultExt – Default file extension to use.

  • fileGroups – Recognised file groups - see getFileGroup().

  • unambiguous – If True (the default), and more than one file exists with the specified prefix, a PathError is raised. Otherwise, a list containing all matching files is returned.

fsl.utils.path.removeExt(filename: str | Path, allowedExts: Sequence[str] | None = None, firstDot: bool = False) str[source]

Returns the base name of the given file name. See splitExt().

fsl.utils.path.getExt(filename: str | Path, allowedExts: Sequence[str] | None = None, firstDot: bool = False) str[source]

Returns the extension of the given file name. See splitExt().

fsl.utils.path.splitExt(filename: str | Path, allowedExts: Sequence[str] | None = None, firstDot: bool = False) Tuple[str, str][source]

Returns the base name and the extension from the given file name.

If allowedExts is None and firstDot is False, this function is equivalent to using:

os.path.splitext(filename)

If allowedExts is None and firstDot is True, the file name is split on the first period that is found, rather than the last period. For example:

splitExt('image.nii.gz')                # -> ('image.nii', '.gz')
splitExt('image.nii.gz', firstDot=True) # -> ('image', '.nii.gz')

If allowedExts is provided, firstDot is ignored. In this case, if the file does not end with an allowed extension, a tuple containing (filename, '') is returned.

Parameters:
  • filename – The file name to split.

  • allowedExts – Allowed/recognised file extensions.

  • firstDot – Split the file name on the first period, rather than the last period. Ignored if allowedExts is specified.

fsl.utils.path.getFileGroup(path, allowedExts=None, fileGroups=None, fullPaths=True, unambiguous=False)[source]

If the given path is part of a fileGroup, returns a list containing the paths to all other files in the group (including the path itself).

If the path does not appear to be part of a file group, or appears to be part of an incomplete file group, a list containing only the path is returned.

If the path does not exist, or appears to be part of more than one file group, a PathError is raised.

File groups can be used to specify a collection of file suffixes which should always exist alongside each other. This can be used to resolve ambiguity when multiple files exist with the same prefix and supported extensions (e.g. file.hdr and file.img). The file groups are specified as a list of sequences, for example:

[('.img',    '.hdr'),
 ('.img.gz', '.hdr.gz')]

If you specify fileGroups=[('.img', '.hdr')] and prefix='file', and both file.img and file.hdr exist, the addExt() function would return file.img (i.e. the file which matches the first extension in the group).

Similarly, if you call the imcp.imcp() or imcp.immv() functions with the above parameters, both file.img and file.hdr will be moved.

Note

The primary use-case of file groups is to resolve ambiguity with respect to NIFTI and ANALYSE75 image pairs. By specifying fileGroups=[('.img', '.hdr'), ('.img.gz', '.hdr.gz')], the addExt(), imcp.immv() and imcp.imcp() functions are able to figure out what you mean when you specify file, and both file.hdr and file.img (or file.hdr.gz and file.img.gz) exist.

Parameters:
  • path – Path to the file. Must contain the file extension.

  • allowedExts – Allowed/recognised file extensions.

  • fileGroups – Recognised file groups.

  • fullPaths – If True (the default), full file paths (relative to the path) are returned. Otherwise, only the file extensions in the group are returned.

  • unambiguous – Defaults to False. If True, and the path is not unambiguously part of one group, or part of no groups, a PathError is raised. Otherwise, the path is returned.

fsl.utils.path.removeDuplicates(paths, allowedExts=None, fileGroups=None)[source]

Reduces the list of paths down to those which are unique with respect to the specified fileGroups.

For example, if you have a directory containing:

001.hdr
001.img
002.hdr
002.img
003.hdr
003.img

And you call removeDuplicates like so:

paths       = ['001.img', '001.hdr',
               '002.img', '002.hdr',
               '003.img', '003.hdr']

allowedExts = ['.img',  '.hdr']
fileGroups  = [('.img', '.hdr')]

removeDuplicates(paths, allowedExts, fileGroups)

The returned list will be:

['001.img', '002.img', '003.img']

If you provide allowedExts, you may specify incomplete paths (i.e. without extensions), as long as there are no path ambiguities.

A PathError will be raised if any of the paths do not exist, or if there are any ambiguities with respect to incomplete paths.

Parameters:
  • paths – List of paths to reduce.

  • allowedExts – Allowed/recognised file extensions.

  • fileGroups – Recognised file groups - see getFileGroup().

fsl.utils.path.uniquePrefix(path)[source]

Return the longest prefix for the given file name which unambiguously identifies it, relative to the other files in the same directory.

Raises a PathError if a unique prefix could not be found (which will never happen if the path is valid).

fsl.utils.path.commonBase(paths)[source]

Identifies the deepest common base directory shared by all files in paths.

Raises a PathError if the paths have no common base. This will never happen for absolute paths (as the base will be e.g. '/').

fsl.utils.path.wslpath(path)[source]

Convert Windows path (or a command line argument containing a Windows path) to the equivalent WSL path (e.g. c:\Users -> /mnt/c/Users). Also supports paths in the form \wsl$\(distro)\users\...

Parameters:

winpath – Command line argument which may (or may not) contain a Windows path. It is assumed to be either of the form <windows path> or –<arg>=<windows path>. Note that we don’t need to handle –arg <windows path> or -a <windows path> since in these cases the argument and the path will be parsed as separate entities.

Returns:

If winpath matches a Windows path, the converted argument (including the –<arg>= portion). Otherwise returns winpath unchanged.

fsl.utils.path.winpath(path)[source]

Convert a WSL-local filepath (for example /usr/local/fsl/) into a path that can be used from Windows.

If self.fslwsl is False, simply returns wslpath unmodified Otherwise, uses FSLDIR to deduce the WSL distro in use for FSL. This requires WSL2 which supports the \wsl$\ network path. wslpath is assumed to be an absolute path.