imglob.py 3.94 KB
Newer Older
Paul McCarthy's avatar
Paul McCarthy committed
1
2
3
4
5
6
#!/usr/bin/env python
#
# imglob.py - Expand image file names.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
Paul McCarthy's avatar
Paul McCarthy committed
7
8
"""This module defines the ``imglob`` application, which identifies unique
NIFTI/ANALYZE image files.
Paul McCarthy's avatar
Paul McCarthy committed
9
10
11
12
"""


import                   sys
13
14
import                   glob
import itertools      as it
Paul McCarthy's avatar
Paul McCarthy committed
15
import fsl.utils.path as fslpath
Paul McCarthy's avatar
Paul McCarthy committed
16

Paul McCarthy's avatar
Paul McCarthy committed
17
18
19
20
21
22
23

usage = """
Usage: imglob [-extension/extensions] <list of names>
       -extension for one image with full extension
       -extensions for image list with full extensions
""".strip()

24
25
26
27
28
29
30
31
32
33
34

# The lists below are defined in the
# fsl.data.image class, but are duplicated
# here for performance (to avoid import of
# nibabel/numpy/etc).
exts   = ['.nii.gz', '.nii', '.img', '.hdr', '.img.gz', '.hdr.gz']
"""List of supported image file extensions. """


groups = [('.hdr',    '.img'), ('.hdr.gz', '.img.gz')]
"""List of known image file groups (image/header file pairs). """
Paul McCarthy's avatar
Paul McCarthy committed
35
36


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def imglob(paths, output=None):
    """Given a list of file names, identifies and returns the unique
    NIFTI/ANALYZE image files that exist.

    :arg paths:  Sequence of paths/prefixes to glob.

    :arg output: One of ``'prefix'`` (the default), ``'all'``, or
                 ``'primary'``:

                  - ``'prefix'``:  Returns the files without extensions.
                  - ``'all'``:     Returns all files that match (e.g. both
                                   ``.img`` and ``.hdr`` files will be
                                   returned).
                  - ``'primary'``: Returns only the primary file of each
                                   matching file group, e.g. only the
                                   ``.hdr`` file would be returned from
                                   an ``.img``/``.hdr`` pair.

    :returns: A sequence of resolved path names, in the form specified
              by the ``output`` parameter.
Paul McCarthy's avatar
Paul McCarthy committed
57
58
    """

59
60
    if output is None:
        output = 'prefix'
Paul McCarthy's avatar
Paul McCarthy committed
61

62
63
    if output not in ('prefix', 'all', 'primary'):
        raise ValueError('Unsupported output format: {}'.format(output))
Paul McCarthy's avatar
Paul McCarthy committed
64

Paul McCarthy's avatar
Paul McCarthy committed
65
    imgfiles = []
Paul McCarthy's avatar
Paul McCarthy committed
66

67
68
69
70
71
72
73
74
75
76
77
78
79
    # Expand any wildcard paths if provided.
    # Depending on the way that imglob is
    # invoked, this may not get done by the
    # calling shell.
    expanded = []
    for path in paths:
        if any(c in path for c in '*?[]'):
            expanded.extend(glob.glob(path))
        else:
            expanded.append(path)

    paths = expanded

Paul McCarthy's avatar
Paul McCarthy committed
80
81
82
83
    # Build a list of all image files (both
    # hdr and img and otherwise) that match
    for path in paths:
        try:
84
85
86
87
            path = fslpath.removeExt(path, allowedExts=exts)
            imgfiles.extend(fslpath.addExt(path,
                                           allowedExts=exts,
                                           unambiguous=False))
Paul McCarthy's avatar
Paul McCarthy committed
88
89
        except fslpath.PathError:
            continue
Paul McCarthy's avatar
Paul McCarthy committed
90

Paul McCarthy's avatar
Paul McCarthy committed
91
92
    if output == 'prefix':
        imgfiles = fslpath.removeDuplicates(imgfiles,
Paul McCarthy's avatar
Paul McCarthy committed
93
94
                                            allowedExts=exts,
                                            fileGroups=groups)
Paul McCarthy's avatar
Paul McCarthy committed
95
96
97
98
        imgfiles = [fslpath.removeExt(f, exts) for f in imgfiles]

    elif output == 'primary':
        imgfiles = fslpath.removeDuplicates(imgfiles,
Paul McCarthy's avatar
Paul McCarthy committed
99
100
101
                                            allowedExts=exts,
                                            fileGroups=groups)

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    return list(sorted(set(imgfiles)))


def main(argv=None):
    """The ``imglob`` application. Given a list of file names, identifies and
    prints the unique NIFTI/ANALYZE image files.
    """

    if argv is None:
        argv = sys.argv[1:]

    if len(argv) < 1:
        print(usage)
        return 1

    if   argv[0] == '-extension':  output = 'primary'
    elif argv[0] == '-extensions': output = 'all'
    else:                          output = 'prefix'

    if output == 'prefix': paths = argv
    else:                  paths = argv[1:]

    imgfiles = imglob(paths, output)
Paul McCarthy's avatar
Paul McCarthy committed
125

126
127
    if len(imgfiles) > 0:
        print(' '.join(imgfiles))
Paul McCarthy's avatar
Paul McCarthy committed
128

Paul McCarthy's avatar
Paul McCarthy committed
129
    return 0
Paul McCarthy's avatar
Paul McCarthy committed
130
131
132
133


if __name__ == '__main__':
    sys.exit(main())