@@ -81,6 +81,106 @@ def error(msg, exit_code):
81
81
print msg
82
82
sys .exit (exit_code )
83
83
84
+ def proc_file (infile , opts ):
85
+ # load the PAR header
86
+ pr_img = pr .load (infile )
87
+ pr_hdr = pr_img .get_header ()
88
+ # get the raw unscaled data form the REC file
89
+ raw_data = read_img_data (pr_img , prefer = 'unscaled' )
90
+
91
+ # compute affine with desired origin
92
+ affine = pr_hdr .get_affine (origin = opts .origin )
93
+
94
+ # create an nifti image instance -- to get a matching header
95
+ nimg = nifti1 .Nifti1Image (raw_data , affine )
96
+ nhdr = nimg .get_header ()
97
+
98
+ if 'parse' in opts .minmax :
99
+ # need to get the scaled data
100
+ verbose ('Load (and scale) the data to determine value range' )
101
+ if opts .scaling == 'off' :
102
+ scaled_data = raw_data
103
+ else :
104
+ slope , intercept = pr_hdr .get_data_scaling (method = opts .scaling )
105
+ scaled_data = slope * raw_data
106
+ scaled_data += intercept
107
+ if opts .minmax [0 ] == 'parse' :
108
+ nhdr .structarr ['cal_min' ] = scaled_data .min ()
109
+ else :
110
+ nhdr .structarr ['cal_min' ] = float (opts .minmax [0 ])
111
+ if opts .minmax [1 ] == 'parse' :
112
+ nhdr .structarr ['cal_max' ] = scaled_data .max ()
113
+ else :
114
+ nhdr .structarr ['cal_max' ] = float (opts .minmax [1 ])
115
+
116
+ # container for potential NIfTI1 header extensions
117
+ exts = nifti1 .Nifti1Extensions ()
118
+
119
+ if opts .store_header :
120
+ # dump the full PAR header content into an extension
121
+ fobj = open (infile , 'r' )
122
+ hdr_dump = fobj .read ()
123
+ dump_ext = nifti1 .Nifti1Extension ('comment' , hdr_dump )
124
+ fobj .close ()
125
+ exts .append (dump_ext )
126
+
127
+ # put any extensions into the image
128
+ nimg .extra ['extensions' ] = exts
129
+
130
+ # image description
131
+ descr = "%s;%s;%s;%s" % (
132
+ pr_hdr .general_info ['exam_name' ],
133
+ pr_hdr .general_info ['patient_name' ],
134
+ pr_hdr .general_info ['exam_date' ].replace (' ' ,'' ),
135
+ pr_hdr .general_info ['protocol_name' ])
136
+ nhdr .structarr ['descrip' ] = descr [:80 ]
137
+
138
+ if pr_hdr .general_info ['max_dynamics' ] > 1 :
139
+ # fMRI
140
+ nhdr .structarr ['pixdim' ][4 ] = pr_hdr .general_info ['repetition_time' ]
141
+ # store units -- always mm and msec
142
+ nhdr .set_xyzt_units ('mm' , 'msec' )
143
+ else :
144
+ # anatomical or DTI
145
+ nhdr .set_xyzt_units ('mm' , 'unknown' )
146
+
147
+ # get original scaling
148
+ if opts .scaling == 'off' :
149
+ slope = 1.0
150
+ intercept = 0.0
151
+ else :
152
+ slope , intercept = pr_hdr .get_data_scaling (method = opts .scaling )
153
+ nhdr .set_slope_inter (slope , intercept )
154
+
155
+ # finalize the header: set proper data offset, pixdims, ...
156
+ nimg .update_header ()
157
+
158
+ # figure out the output filename
159
+ outfilename = splitext_addext (os .path .basename (infile ))[0 ]
160
+ if not opts .outdir is None :
161
+ # set output path
162
+ outfilename = os .path .join (opts .outdir , outfilename )
163
+
164
+ # prep a file
165
+ if opts .compressed :
166
+ verbose ('Using gzip compression' )
167
+ outfilename += '.nii.gz'
168
+ outfile = gzip .open (outfilename , 'w' )
169
+ else :
170
+ outfilename += '.nii'
171
+ outfile = open (outfilename , 'w' )
172
+
173
+ verbose ('Writing %s' % outfilename )
174
+ # first write the header
175
+ nimg ._write_header (outfile , nhdr , slope , intercept )
176
+ # now the data itself, but prevent any casting or scaling
177
+ nibabel .volumeutils .array_to_file (
178
+ raw_data ,
179
+ outfile ,
180
+ offset = nhdr .get_data_offset ())
181
+ # done
182
+ outfile .close ()
183
+
84
184
85
185
def main ():
86
186
parser = get_opt_parser ()
@@ -92,107 +192,20 @@ def main():
92
192
if not opts .origin in ['scanner' , 'fov' ]:
93
193
error ("Unrecognized value for --origin: '%s'." % opts .origin , 1 )
94
194
195
+ # store any exceptions
196
+ errs = []
95
197
for infile in infiles :
96
198
verbose ('Processing %s' % infile )
97
- # load the PAR header
98
- pr_img = pr .load (infile )
99
- pr_hdr = pr_img .get_header ()
100
- # get the raw unscaled data form the REC file
101
- raw_data = read_img_data (pr_img , prefer = 'unscaled' )
102
-
103
- # compute affine with desired origin
104
- affine = pr_hdr .get_affine (origin = opts .origin )
105
-
106
- # create an nifti image instance -- to get a matching header
107
- nimg = nifti1 .Nifti1Image (raw_data , affine )
108
- nhdr = nimg .get_header ()
109
-
110
- if 'parse' in opts .minmax :
111
- # need to get the scaled data
112
- verbose ('Load (and scale) the data to determine value range' )
113
- if opts .scaling == 'off' :
114
- scaled_data = raw_data
115
- else :
116
- slope , intercept = pr_hdr .get_data_scaling (method = opts .scaling )
117
- scaled_data = slope * raw_data
118
- scaled_data += intercept
119
- if opts .minmax [0 ] == 'parse' :
120
- nhdr .structarr ['cal_min' ] = scaled_data .min ()
121
- else :
122
- nhdr .structarr ['cal_min' ] = float (opts .minmax [0 ])
123
- if opts .minmax [1 ] == 'parse' :
124
- nhdr .structarr ['cal_max' ] = scaled_data .max ()
125
- else :
126
- nhdr .structarr ['cal_max' ] = float (opts .minmax [1 ])
127
-
128
- # container for potential NIfTI1 header extensions
129
- exts = nifti1 .Nifti1Extensions ()
130
-
131
- if opts .store_header :
132
- # dump the full PAR header content into an extension
133
- fobj = open (infile , 'r' )
134
- hdr_dump = fobj .read ()
135
- dump_ext = nifti1 .Nifti1Extension ('comment' , hdr_dump )
136
- fobj .close ()
137
- exts .append (dump_ext )
138
-
139
- # put any extensions into the image
140
- nimg .extra ['extensions' ] = exts
141
-
142
- # image description
143
- descr = "%s;%s;%s;%s" % (
144
- pr_hdr .general_info ['exam_name' ],
145
- pr_hdr .general_info ['patient_name' ],
146
- pr_hdr .general_info ['exam_date' ].replace (' ' ,'' ),
147
- pr_hdr .general_info ['protocol_name' ])
148
- nhdr .structarr ['descrip' ] = descr [:80 ]
149
-
150
- if pr_hdr .general_info ['max_dynamics' ] > 1 :
151
- # fMRI
152
- nhdr .structarr ['pixdim' ][4 ] = pr_hdr .general_info ['repetition_time' ]
153
- # store units -- always mm and msec
154
- nhdr .set_xyzt_units ('mm' , 'msec' )
155
- else :
156
- # anatomical or DTI
157
- nhdr .set_xyzt_units ('mm' , 'unknown' )
158
-
159
- # get original scaling
160
- if opts .scaling == 'off' :
161
- slope = 1.0
162
- intercept = 0.0
163
- else :
164
- slope , intercept = pr_hdr .get_data_scaling (method = opts .scaling )
165
- nhdr .set_slope_inter (slope , intercept )
166
-
167
- # finalize the header: set proper data offset, pixdims, ...
168
- nimg .update_header ()
169
-
170
- # figure out the output filename
171
- outfilename = splitext_addext (os .path .basename (infile ))[0 ]
172
- if not opts .outdir is None :
173
- # set output path
174
- outfilename = os .path .join (opts .outdir , outfilename )
175
-
176
- # prep a file
177
- if opts .compressed :
178
- verbose ('Using gzip compression' )
179
- outfilename += '.nii.gz'
180
- outfile = gzip .open (outfilename , 'w' )
181
- else :
182
- outfilename += '.nii'
183
- outfile = open (outfilename , 'w' )
184
-
185
- verbose ('Writing %s' % outfilename )
186
- # first write the header
187
- nimg ._write_header (outfile , nhdr , slope , intercept )
188
- # now the data itself, but prevent any casting or scaling
189
- nibabel .volumeutils .array_to_file (
190
- raw_data ,
191
- outfile ,
192
- offset = nhdr .get_data_offset ())
193
- # done
194
- outfile .close ()
195
-
199
+ try :
200
+ proc_file (infile , opts )
201
+ except Exception as err :
202
+ errs .append ('%s: %s' % (infile , err ))
203
+
204
+ if len (errs ):
205
+ error ('Caught %i exceptions. Dump follows:\n \n %s'
206
+ % (len (errs ), '\n ' .join (errs )), 1 )
207
+ else :
208
+ verbose ('Done' )
196
209
197
210
198
211
if __name__ == '__main__' :
0 commit comments