imglob.py 3.91 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
import                   glob
Paul McCarthy's avatar
Paul McCarthy committed
14
import fsl.utils.path as fslpath
Paul McCarthy's avatar
Paul McCarthy committed
15

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

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

23
24
25
26
27
28
29
30
31

# 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. """


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


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
56
57
    """

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

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

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

66
67
68
69
70
71
72
73
74
75
76
77
78
    # 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
79
80
81
82
    # Build a list of all image files (both
    # hdr and img and otherwise) that match
    for path in paths:
        try:
83
84
85
86
            path = fslpath.removeExt(path, allowedExts=exts)
            imgfiles.extend(fslpath.addExt(path,
                                           allowedExts=exts,
                                           unambiguous=False))
Paul McCarthy's avatar
Paul McCarthy committed
87
88
        except fslpath.PathError:
            continue
Paul McCarthy's avatar
Paul McCarthy committed
89

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

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

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    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
124

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

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


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