@@ -1165,7 +1165,172 @@ def normalize_tpms(in_files, in_mask=None, out_files=[]):
1165
1165
return out_files
1166
1166
1167
1167
1168
- # Deprecated interfaces ---------------------------------------------------------
1168
+ def split_rois (in_file , mask = None , roishape = None ):
1169
+ """
1170
+ Splits an image in ROIs for parallel processing
1171
+ """
1172
+ import nibabel as nb
1173
+ import numpy as np
1174
+ from math import sqrt , ceil
1175
+ import os .path as op
1176
+
1177
+ if roishape is None :
1178
+ roishape = (10 , 10 , 1 )
1179
+
1180
+ im = nb .load (in_file )
1181
+ imshape = im .get_shape ()
1182
+ dshape = imshape [:3 ]
1183
+ nvols = imshape [- 1 ]
1184
+ roisize = roishape [0 ] * roishape [1 ] * roishape [2 ]
1185
+ droishape = (roishape [0 ], roishape [1 ], roishape [2 ], nvols )
1186
+
1187
+ if mask is not None :
1188
+ mask = nb .load (mask ).get_data ()
1189
+ mask [mask > 0 ] = 1
1190
+ mask [mask < 1 ] = 0
1191
+ else :
1192
+ mask = np .ones (dshape )
1193
+
1194
+ mask = mask .reshape (- 1 ).astype (np .uint8 )
1195
+ nzels = np .nonzero (mask )
1196
+ els = np .sum (mask )
1197
+ nrois = int (ceil (els / roisize ))
1198
+
1199
+ data = im .get_data ().reshape ((mask .size , - 1 ))
1200
+ data = np .squeeze (data .take (nzels , axis = 0 ))
1201
+ nvols = data .shape [- 1 ]
1202
+
1203
+ roidefname = op .abspath ('onesmask.nii.gz' )
1204
+ nb .Nifti1Image (np .ones (roishape , dtype = np .uint8 ), None ,
1205
+ None ).to_filename (roidefname )
1206
+
1207
+ out_files = []
1208
+ out_mask = []
1209
+ out_idxs = []
1210
+
1211
+ for i in xrange (nrois ):
1212
+ first = i * roisize
1213
+ last = (i + 1 ) * roisize
1214
+ fill = 0
1215
+
1216
+ if last > els :
1217
+ fill = last - els
1218
+ last = els
1219
+
1220
+ droi = data [first :last , ...]
1221
+ iname = op .abspath ('roi%010d_idx' % i )
1222
+ out_idxs .append (iname + '.npz' )
1223
+ np .savez (iname , (nzels [0 ][first :last ],))
1224
+
1225
+ if fill > 0 :
1226
+ droi = np .vstack ((droi , np .zeros ((fill , nvols ), dtype = np .float32 )))
1227
+ partialmsk = np .ones ((roisize ,), dtype = np .uint8 )
1228
+ partialmsk [- fill :] = 0
1229
+ partname = op .abspath ('partialmask.nii.gz' )
1230
+ nb .Nifti1Image (partialmsk .reshape (roishape ), None ,
1231
+ None ).to_filename (partname )
1232
+ out_mask .append (partname )
1233
+ else :
1234
+ out_mask .append (roidefname )
1235
+
1236
+ fname = op .abspath ('roi%010d.nii.gz' % i )
1237
+ nb .Nifti1Image (droi .reshape (droishape ),
1238
+ None , None ).to_filename (fname )
1239
+ out_files .append (fname )
1240
+ return out_files , out_mask , out_idxs
1241
+
1242
+
1243
+ def merge_rois (in_files , in_idxs , in_ref ,
1244
+ dtype = None , out_file = None ):
1245
+ """
1246
+ Re-builds an image resulting from a parallelized processing
1247
+ """
1248
+ import nibabel as nb
1249
+ import numpy as np
1250
+ import os .path as op
1251
+ import subprocess as sp
1252
+
1253
+ if out_file is None :
1254
+ out_file = op .abspath ('merged.nii.gz' )
1255
+
1256
+ if dtype is None :
1257
+ dtype = np .float32
1258
+
1259
+ # if file is compressed, uncompress using os
1260
+ # to avoid memory errors
1261
+ if op .splitext (in_ref )[1 ] == '.gz' :
1262
+ try :
1263
+ iflogger .info ('uncompress %i' % in_ref )
1264
+ sp .check_call (['gunzip' , in_ref ], stdout = sp .PIPE , shell = True )
1265
+ in_ref = op .splitext (in_ref )[0 ]
1266
+ except :
1267
+ pass
1268
+
1269
+ ref = nb .load (in_ref )
1270
+ aff = ref .get_affine ()
1271
+ hdr = ref .get_header ().copy ()
1272
+ rsh = ref .get_shape ()
1273
+ del ref
1274
+ npix = rsh [0 ] * rsh [1 ] * rsh [2 ]
1275
+ fcdata = nb .load (in_files [0 ]).get_data ()
1276
+
1277
+ if fcdata .ndim == 4 :
1278
+ ndirs = fcdata .shape [- 1 ]
1279
+ else :
1280
+ ndirs = 1
1281
+ newshape = (rsh [0 ], rsh [1 ], rsh [2 ], ndirs )
1282
+ hdr .set_data_dtype (dtype )
1283
+ hdr .set_xyzt_units ('mm' , 'sec' )
1284
+
1285
+ if ndirs < 300 :
1286
+ data = np .zeros ((npix , ndirs ))
1287
+ for cname , iname in zip (in_files , in_idxs ):
1288
+ with np .load (iname ) as f :
1289
+ idxs = np .squeeze (f ['arr_0' ])
1290
+ cdata = nb .load (cname ).get_data ().reshape (- 1 , ndirs )
1291
+ nels = len (idxs )
1292
+ idata = (idxs , )
1293
+ try :
1294
+ data [idata , ...] = cdata [0 :nels , ...]
1295
+ except :
1296
+ print (data .shape , cdata .shape )
1297
+ raise
1298
+
1299
+ hdr .set_data_shape (newshape )
1300
+
1301
+ nb .Nifti1Image (data .reshape (newshape ).astype (dtype ),
1302
+ aff , hdr ).to_filename (out_file )
1303
+
1304
+
1305
+ else :
1306
+ hdr .set_data_shape (rsh [:3 ])
1307
+ nii = []
1308
+ for d in xrange (ndirs ):
1309
+ fname = op .abspath ('vol%06d.nii' % d )
1310
+ nb .Nifti1Image (np .zeros (rsh [:3 ]), aff , hdr ).to_filename (fname )
1311
+ nii .append (fname )
1312
+
1313
+ for cname , iname in zip (in_files , in_idxs ):
1314
+ with np .load (iname ) as f :
1315
+ idxs = np .squeeze (f ['arr_0' ])
1316
+
1317
+ for d , fname in enumerate (nii ):
1318
+ data = nb .load (fname ).get_data ().reshape (- 1 )
1319
+ cdata = nb .load (cname ).get_data ().reshape (- 1 , ndirs )[:, d ]
1320
+ nels = len (idxs )
1321
+ idata = (idxs , )
1322
+ data [idata ] = cdata [0 :nels ]
1323
+ nb .Nifti1Image (data .reshape (rsh [:3 ]), aff , hdr ).to_filename (fname )
1324
+
1325
+ imgs = [nb .load (im ) for im in nii ]
1326
+ allim = nb .concat_images (imgs )
1327
+ allim .to_filename (out_file )
1328
+
1329
+ return out_file
1330
+
1331
+
1332
+ # Deprecated interfaces ------------------------------------------------------
1333
+
1169
1334
class Distance (nam .Distance ):
1170
1335
"""Calculates distance between two volumes.
1171
1336
0 commit comments