@@ -48,23 +48,50 @@ def create_annot_label(subject_id, subjects_dir, fs_dir, parcellation_name):
48
48
os .makedirs (op .join ('.' , p ))
49
49
except :
50
50
pass
51
+ if '33' in parcellation_name :
52
+ comp = [
53
+ ('rh' , 'myatlas_36_rh.gcs' , 'rh.myaparc_36.annot' , 'regenerated_rh_36' ,'myaparc_36' ),
54
+ ('rh' ,'myatlas_60_rh.gcs' ,'rh.myaparc_60.annot' ,'regenerated_rh_60' ,'myaparc_60' ),
55
+ ('lh' , 'myatlas_36_lh.gcs' , 'lh.myaparc_36.annot' , 'regenerated_lh_36' ,'myaparc_36' ),
56
+ ('lh' ,'myatlas_60_lh.gcs' ,'lh.myaparc_60.annot' ,'regenerated_lh_60' , 'myaparc_60' ),
57
+ ]
58
+ elif '60' in parcellation_name :
59
+ comp = [
60
+ ('rh' ,'myatlas_60_rh.gcs' ,'rh.myaparc_60.annot' ,'regenerated_rh_60' ,'myaparc_60' ),
61
+ ('lh' ,'myatlas_60_lh.gcs' ,'lh.myaparc_60.annot' ,'regenerated_lh_60' , 'myaparc_60' ),
62
+ ]
63
+ elif '125' in parcellation_name :
64
+ comp = [
65
+ ('rh' ,'myatlas_125_rh.gcs' ,'rh.myaparc_125.annot' ,'regenerated_rh_125' ,'myaparc_125' ),
66
+ ('rh' ,'myatlas_60_rh.gcs' ,'rh.myaparc_60.annot' ,'regenerated_rh_60' ,'myaparc_60' ),
67
+ ('lh' ,'myatlas_125_lh.gcs' ,'lh.myaparc_125.annot' ,'regenerated_lh_125' ,'myaparc_125' ),
68
+ ('lh' ,'myatlas_60_lh.gcs' ,'lh.myaparc_60.annot' ,'regenerated_lh_60' , 'myaparc_60' ),
69
+ ]
70
+ elif '250' in parcellation_name :
71
+ comp = [
72
+ ('rh' ,'myatlas_250_rh.gcs' ,'rh.myaparc_250.annot' ,'regenerated_rh_250' ,'myaparc_250' ),
73
+ ('rh' ,'myatlas_60_rh.gcs' ,'rh.myaparc_60.annot' ,'regenerated_rh_60' ,'myaparc_60' ),
74
+ ('lh' ,'myatlas_250_lh.gcs' ,'lh.myaparc_250.annot' ,'regenerated_lh_250' ,'myaparc_250' ),
75
+ ('lh' ,'myatlas_60_lh.gcs' ,'lh.myaparc_60.annot' ,'regenerated_lh_60' , 'myaparc_60' ),
76
+ ]
77
+ else :
78
+ comp = [
79
+ ('rh' , 'myatlas_36_rh.gcs' , 'rh.myaparc_36.annot' , 'regenerated_rh_36' ,'myaparc_36' ),
80
+ ('rh' , 'myatlasP1_16_rh.gcs' ,'rh.myaparcP1_16.annot' ,'regenerated_rh_500' ,'myaparcP1_16' ),
81
+ ('rh' , 'myatlasP17_28_rh.gcs' ,'rh.myaparcP17_28.annot' ,'regenerated_rh_500' ,'myaparcP17_28' ),
82
+ ('rh' , 'myatlasP29_36_rh.gcs' ,'rh.myaparcP29_36.annot' ,'regenerated_rh_500' ,'myaparcP29_36' ),
83
+ ('rh' ,'myatlas_60_rh.gcs' ,'rh.myaparc_60.annot' ,'regenerated_rh_60' ,'myaparc_60' ),
84
+ ('rh' ,'myatlas_125_rh.gcs' ,'rh.myaparc_125.annot' ,'regenerated_rh_125' ,'myaparc_125' ),
85
+ ('rh' ,'myatlas_250_rh.gcs' ,'rh.myaparc_250.annot' ,'regenerated_rh_250' ,'myaparc_250' ),
86
+ ('lh' , 'myatlas_36_lh.gcs' , 'lh.myaparc_36.annot' , 'regenerated_lh_36' ,'myaparc_36' ),
87
+ ('lh' , 'myatlasP1_16_lh.gcs' ,'lh.myaparcP1_16.annot' ,'regenerated_lh_500' ,'myaparcP1_16' ),
88
+ ('lh' , 'myatlasP17_28_lh.gcs' ,'lh.myaparcP17_28.annot' ,'regenerated_lh_500' ,'myaparcP17_28' ),
89
+ ('lh' , 'myatlasP29_36_lh.gcs' ,'lh.myaparcP29_36.annot' ,'regenerated_lh_500' ,'myaparcP29_36' ),
90
+ ('lh' ,'myatlas_60_lh.gcs' ,'lh.myaparc_60.annot' ,'regenerated_lh_60' , 'myaparc_60' ),
91
+ ('lh' ,'myatlas_125_lh.gcs' ,'lh.myaparc_125.annot' ,'regenerated_lh_125' ,'myaparc_125' ),
92
+ ('lh' ,'myatlas_250_lh.gcs' ,'lh.myaparc_250.annot' ,'regenerated_lh_250' ,'myaparc_250' ),
93
+ ]
51
94
52
- comp = [
53
- ('rh' , 'myatlas_36_rh.gcs' , 'rh.myaparc_36.annot' , 'regenerated_rh_36' ,'myaparc_36' ),
54
- ('rh' , 'myatlasP1_16_rh.gcs' ,'rh.myaparcP1_16.annot' ,'regenerated_rh_500' ,'myaparcP1_16' ),
55
- ('rh' , 'myatlasP17_28_rh.gcs' ,'rh.myaparcP17_28.annot' ,'regenerated_rh_500' ,'myaparcP17_28' ),
56
- ('rh' , 'myatlasP29_36_rh.gcs' ,'rh.myaparcP29_36.annot' ,'regenerated_rh_500' ,'myaparcP29_36' ),
57
- ('rh' ,'myatlas_60_rh.gcs' ,'rh.myaparc_60.annot' ,'regenerated_rh_60' ,'myaparc_60' ),
58
- ('rh' ,'myatlas_125_rh.gcs' ,'rh.myaparc_125.annot' ,'regenerated_rh_125' ,'myaparc_125' ),
59
- ('rh' ,'myatlas_250_rh.gcs' ,'rh.myaparc_250.annot' ,'regenerated_rh_250' ,'myaparc_250' ),
60
- ('lh' , 'myatlas_36_lh.gcs' , 'lh.myaparc_36.annot' , 'regenerated_lh_36' ,'myaparc_36' ),
61
- ('lh' , 'myatlasP1_16_lh.gcs' ,'lh.myaparcP1_16.annot' ,'regenerated_lh_500' ,'myaparcP1_16' ),
62
- ('lh' , 'myatlasP17_28_lh.gcs' ,'lh.myaparcP17_28.annot' ,'regenerated_lh_500' ,'myaparcP17_28' ),
63
- ('lh' , 'myatlasP29_36_lh.gcs' ,'lh.myaparcP29_36.annot' ,'regenerated_lh_500' ,'myaparcP29_36' ),
64
- ('lh' ,'myatlas_60_lh.gcs' ,'lh.myaparc_60.annot' ,'regenerated_lh_60' , 'myaparc_60' ),
65
- ('lh' ,'myatlas_125_lh.gcs' ,'lh.myaparc_125.annot' ,'regenerated_lh_125' ,'myaparc_125' ),
66
- ('lh' ,'myatlas_250_lh.gcs' ,'lh.myaparc_250.annot' ,'regenerated_lh_250' ,'myaparc_250' ),
67
- ]
68
95
log = cmp_config .get_logger ()
69
96
70
97
for out in comp :
@@ -116,6 +143,25 @@ def create_roi(subject_id, subjects_dir, fs_dir, parcellation_name):
116
143
aseg = nb .load (op .join (fs_dir , 'mri' , 'aseg.nii.gz' ))
117
144
asegd = aseg .get_data ()
118
145
146
+ # identify cortical voxels, right (3) and left (42) hemispheres
147
+ idxr = np .where (asegd == 3 )
148
+ idxl = np .where (asegd == 42 )
149
+ xx = np .concatenate ((idxr [0 ],idxl [0 ]))
150
+ yy = np .concatenate ((idxr [1 ],idxl [1 ]))
151
+ zz = np .concatenate ((idxr [2 ],idxl [2 ]))
152
+
153
+ # initialize variables necessary for cortical ROIs dilation
154
+ # dimensions of the neighbourhood for rois labels assignment (choose odd dimensions!)
155
+ shape = (25 ,25 ,25 )
156
+ center = np .array (shape ) // 2
157
+ # dist: distances from the center of the neighbourhood
158
+ dist = np .zeros (shape , dtype = 'float32' )
159
+ for x in range (shape [0 ]):
160
+ for y in range (shape [1 ]):
161
+ for z in range (shape [2 ]):
162
+ distxyz = center - [x ,y ,z ]
163
+ dist [x ,y ,z ] = np .sqrt (np .sum (np .multiply (distxyz ,distxyz )))
164
+
119
165
iflogger .info ("Working on parcellation: " )
120
166
iflogger .info (cmp_config ._get_lausanne_parcellation ('Lausanne2008' )[parcellation_name ])
121
167
iflogger .info ("========================" )
@@ -186,10 +232,9 @@ def create_roi(subject_id, subjects_dir, fs_dir, parcellation_name):
186
232
iflogger .info ("[ DONE ]" )
187
233
# dilate cortical regions
188
234
iflogger .info ("Dilating cortical regions..." )
189
- dilatestart = time ()
190
235
# loop throughout all the voxels belonging to the aseg GM volume
191
236
for j in range (xx .size ):
192
- if newrois [xx [j ],yy [j ],zz [j ]] == 0 :
237
+ if rois [xx [j ],yy [j ],zz [j ]] == 0 :
193
238
local = extract (rois , shape , position = (xx [j ],yy [j ],zz [j ]), fill = 0 )
194
239
mask = local .copy ()
195
240
mask [np .nonzero (local > 0 )] = 1
@@ -199,13 +244,13 @@ def create_roi(subject_id, subjects_dir, fs_dir, parcellation_name):
199
244
if value .size > 1 :
200
245
counts = np .bincount (value )
201
246
value = np .argmax (counts )
202
- newrois [xx [j ],yy [j ],zz [j ]] = value
247
+ rois [xx [j ],yy [j ],zz [j ]] = value
203
248
204
249
# store volume eg in ROIv_scale33.nii.gz
205
- out_roi = op .join (fs_dir , 'label' , ' ROIv_%s.nii.gz' % parkey )
250
+ out_roi = op .join (output_dir , 'ROIv_%s.nii.gz' % parcellation_name )
206
251
iflogger .info ("Save output image to %s" % out_roi )
207
- img = ni .Nifti1Image (newrois , aseg .get_affine (), hdr2 )
208
- ni .save (img , out_roi )
252
+ img = nb .Nifti1Image (rois , aseg .get_affine (), hdr2 )
253
+ nb .save (img , out_roi )
209
254
210
255
iflogger .info ("[ DONE ]" )
211
256
@@ -364,6 +409,7 @@ def crop_and_move_datasets(subject_id, subjects_dir, fs_dir, parcellation_name,
364
409
]
365
410
366
411
ds .append ( (op .join (op .curdir , 'ROI_%s.nii.gz' % parcellation_name ), op .join (op .curdir , 'ROI_HR_th.nii.gz' )) )
412
+ ds .append ( (op .join (op .curdir , 'ROIv_%s.nii.gz' % parcellation_name ), op .join (op .curdir , 'ROIv_HR_th.nii.gz' )) )
367
413
orig = op .join (fs_dir , 'mri' , 'orig' , '001.mgz' )
368
414
for d in ds :
369
415
iflogger .info ("Processing %s:" % d [0 ])
@@ -374,6 +420,35 @@ def crop_and_move_datasets(subject_id, subjects_dir, fs_dir, parcellation_name,
374
420
mri_cmd = 'mri_convert -rl "%s" -rt nearest "%s" -nc "%s"' % (orig , d [0 ], d [1 ])
375
421
runCmd ( mri_cmd ,log )
376
422
423
+ def extract (Z , shape , position , fill ):
424
+ """ Extract voxel neighbourhood
425
+ Parameters
426
+ ----------
427
+ Z: the original data
428
+ shape: tuple containing neighbourhood dimensions
429
+ position: tuple containing central point indexes
430
+ fill: value for the padding of Z
431
+ Returns
432
+ -------
433
+ R: the neighbourhood of the specified point in Z
434
+ """
435
+ R = np .ones (shape , dtype = Z .dtype ) * fill # initialize output block to the fill value
436
+ P = np .array (list (position )).astype (int ) # position coordinates(numpy array)
437
+ Rs = np .array (list (R .shape )).astype (int ) # output block dimensions (numpy array)
438
+ Zs = np .array (list (Z .shape )).astype (int ) # original volume dimensions (numpy array)
439
+
440
+ R_start = np .zeros (len (shape )).astype (int )
441
+ R_stop = np .array (list (shape )).astype (int )
442
+ Z_start = (P - Rs // 2 )
443
+ Z_start_cor = (np .maximum (Z_start ,0 )).tolist () # handle borders
444
+ R_start = R_start + (Z_start_cor - Z_start )
445
+ Z_stop = (P + Rs // 2 ) + Rs % 2
446
+ Z_stop_cor = (np .minimum (Z_stop ,Zs )).tolist () # handle borders
447
+ R_stop = R_stop - (Z_stop - Z_stop_cor )
448
+
449
+ R [R_start [0 ]:R_stop [0 ], R_start [1 ]:R_stop [1 ], R_start [2 ]:R_stop [2 ]] = Z [Z_start_cor [0 ]:Z_stop_cor [0 ], Z_start_cor [1 ]:Z_stop_cor [1 ], Z_start_cor [2 ]:Z_stop_cor [2 ]]
450
+
451
+ return R
377
452
378
453
class ParcellateInputSpec (BaseInterfaceInputSpec ):
379
454
subject_id = traits .String (mandatory = True , desc = 'Subject ID' )
@@ -425,9 +500,9 @@ def _run_interface(self, runtime):
425
500
raise Exception
426
501
iflogger .info ("ROI_HR_th.nii.gz / fsmask_1mm.nii.gz CREATION" )
427
502
iflogger .info ("=============================================" )
428
- create_annot_label (self .inputs .subject_id , self .inputs .subjects_dir , self .inputs .freesurfer_dir , self .inputs .parcellation_name )
503
+ # create_annot_label(self.inputs.subject_id, self.inputs.subjects_dir, self.inputs.freesurfer_dir, self.inputs.parcellation_name)
429
504
create_roi (self .inputs .subject_id , self .inputs .subjects_dir , self .inputs .freesurfer_dir , self .inputs .parcellation_name )
430
- create_wm_mask (self .inputs .subject_id , self .inputs .subjects_dir , self .inputs .freesurfer_dir , self .inputs .parcellation_name )
505
+ # create_wm_mask(self.inputs.subject_id, self.inputs.subjects_dir, self.inputs.freesurfer_dir, self.inputs.parcellation_name)
431
506
crop_and_move_datasets (self .inputs .subject_id , self .inputs .subjects_dir , self .inputs .freesurfer_dir , self .inputs .parcellation_name , self .inputs .out_roi_file )
432
507
return runtime
433
508
0 commit comments