File: tff_generate_trx_from_scratch.py

package info (click to toggle)
python-trx-python 0.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 408 kB
  • sloc: python: 3,394; makefile: 66
file content (140 lines) | stat: -rwxr-xr-x 6,543 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Generate TRX file from a collection of CSV, TXT or NPY files by individually
specifying positions, offsets, data_per_vertex, data_per_streamlines,
groups and data_per_group. Each file must have its data type specified by the
users.

A reference file must be provided (NIFTI) and the option --verify_invalid will
remove invalid streamlines (outside of the bounding box in VOX space).

All dimensions (nbr_vertices and nbr_streamlines) and groups/dpg must match
otherwise the script will (likely) crash.

Each instance of --dps, --dpv, --groups require 2 arguments (FILE, DTYPE).
--dpg requires 3 arguments (GROUP, FILE, DTYPE).
The choice of DTYPE are:
    - (u)int8, (u)int16, (u)int32, (u)int64
    - float16, float32, float64
    - bool

Example command:
tff_generate_trx_from_scratch.py fa.nii.gz generated.trx -f \
    --positions test_npy/positions.npy --positions_dtype float16 \
    --offsets test_npy/offsets.npy --offsets_dtype uint32 \
    --dpv test_npy/dpv_cx.npy uint8 \
    --dpv test_npy/dpv_cy.npy uint8 \
    --dpv test_npy/dpv_cz.npy uint8 \
    --dps test_npy/dps_algo.npy uint8 \
    --dps test_npy/dps_cw.npy float64 \
    --groups test_npy/g_AF_L.npy int32 \
    --groups test_npy/g_AF_R.npy int32 \
    --dpg g_AF_L test_npy/dpg_AF_L_mean_fa.npy float32 \
    --dpg g_AF_R test_npy/dpg_AF_R_mean_fa.npy float32 \
    --dpg g_AF_L test_npy/dpg_AF_L_volume.npy float32
"""

import argparse
import os

from trx.workflows import generate_trx_from_scratch


def _build_arg_parser():
    p = argparse.ArgumentParser(description=__doc__,
                                formatter_class=argparse.RawTextHelpFormatter)
    p.add_argument('reference',
                   help='Reference anatomy for tck/vtk/fib/dpy file\n'
                   'support (.nii or .nii.gz).')
    p.add_argument('out_tractogram', metavar='OUT_TRACTOGRAM',
                   help='Output filename. Format must be one of\n'
                        'trk, tck, vtk, fib, dpy, trx.')

    p1 = p.add_argument_group(title='Positions options')
    p1.add_argument('--positions', metavar='POSITIONS',
                    help='Binary file containing the streamlines coordinates.'
                         '\nMust be Nx3 (.npy)')
    p1.add_argument('--offsets', metavar='OFFSETS',
                    help='Binary file containing the streamlines offsets (.npy)')
    p1.add_argument('--positions_csv', metavar='POSITIONS',
                    help='CSV file containing the streamlines coordinates.'
                         '\nRows for each streamlines organized as x1,y1,z1,\n'
                         'x2,y2,z2,...,xN,yN,zN')
    p1.add_argument('--space', choices=['RASMM', 'VOXMM', 'VOX'],
                    default='RASMM',
                    help='Space in which the coordinates are declared.'
                         '[%(default)s]\nNon-default option requires Dipy.')
    p1.add_argument('--origin', choices=['NIFTI', 'TRACKVIS'],
                    default='NIFTI',
                    help='Origin in which the coordinates are declared. '
                         '[%(default)s]\nNon-default option requires Dipy.')
    p2 = p.add_argument_group(title='Data type options')
    p2.add_argument('--positions_dtype', default='float32',
                    choices=['float16', 'float32', 'float64'],
                    help='Specify the datatype for positions for trx. '
                         '[%(default)s]')
    p2.add_argument('--offsets_dtype', default='uint64',
                    choices=['uint32', 'uint64'],
                    help='Specify the datatype for offsets for trx. '
                         '[%(default)s]')

    p3 = p.add_argument_group(title='Streamlines metadata options')
    p3.add_argument('--dpv', metavar=('FILE', 'DTYPE'), nargs=2,
                    action='append',
                    help='Binary file containing data_per_vertex.\n Must have'
                         'NB_VERTICES as first dimension (.npy)')
    p3.add_argument('--dps', metavar=('FILE', 'DTYPE'), nargs=2,
                    action='append',
                    help='Binary file containing data_per_vertex.\n Must have'
                         'NB_STREAMLINES as first dimension (.npy)')
    p3.add_argument('--groups', metavar=('FILE', 'DTYPE'), nargs=2,
                    action='append',
                    help='Binary file containing a sparse group (indices).\n '
                         'Indices should be lower than NB_STREAMLINES (.npy)')
    p3.add_argument('--dpg', metavar=('GROUP', 'FILE', 'DTYPE'), nargs=3,
                    action='append',
                    help='Binary file containing data_per_group.\n Must have'
                         '(1,) as first dimension (.npy)')

    p.add_argument('--verify_invalid', action='store_true',
                   help='Verify that the positions are all valid.\n'
                        'None outside of the bounding box in VOX space.\n'
                        'Requires Dipy (due to use of SFT).')
    p.add_argument('-f', dest='overwrite', action='store_true',
                   help='Force overwriting of the output files.')

    return p


def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    if os.path.isfile(args.out_tractogram) and not args.overwrite:
        raise IOError('{} already exists, use -f to overwrite.'.format(
            args.out_tractogram))

    if not args.positions and not args.positions_csv:
        parser.error('At least one positions options must be used.')
    if args.positions_csv and args.positions:
        parser.error('Cannot use both positions options.')
    if args.positions and args.offsets is None:
        parser.error('--offsets must be provided if --positions is used.')
    if args.offsets and args.positions is None:
        parser.error('--positions must be provided if --offsets is used.')

    generate_trx_from_scratch(args.reference, args.out_tractogram,
                              positions_csv=args.positions_csv,
                              positions=args.positions, offsets=args.offsets,
                              positions_dtype=args.positions_dtype,
                              offsets_dtype=args.offsets_dtype,
                              space_str=args.space, origin_str=args.origin,
                              verify_invalid=args.verify_invalid,
                              dpv=args.dpv, dps=args.dps,
                              groups=args.groups, dpg=args.dpg)


if __name__ == "__main__":
    main()