def roi_extract(self, inputs, outputs): ''' ''' # check if we have all required input data # we need at least: # - outputs['fibers_mapped'] == Track file in T1 space with mapped scalars if not os.path.exists(outputs['fibers_final']): c.error(Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['fibers_final'] + Colors.RED + ' but we really need it to start with stage 6!!' + Colors._CLEAR) sys.exit(2) s = io.loadTrk(outputs['fibers_final']) tracks = s[0] header = s[1] scalarNames = header['scalar_name'].tolist() labels = {} # check if the segmentation is mapped try: seg_index = scalarNames.index('segmentation') except: c.error(Colors.RED + 'Could not find ' + Colors.YELLOW + 'segmentation' + Colors.RED + ' as a mapped scalar but we really need it!') sys.exit(2) # create the roi subfolder if not os.path.exists(outputs['roi']): os.mkdir(outputs['roi']) # parse the color table lut = fyborg.colortable.freesurfer.split('\n') colors = {} for color in lut: if not color or color[0] == '#': continue splitted_line = color.split(' ') splitted_line = filter(None, splitted_line) colors[splitted_line[0]] = splitted_line[1] # loop through tracks for i, t in enumerate(tracks): tCoordinates = t[0] tScalars = t[1] # grab the scalars for each point for scalar in tScalars: # but only the label value label_value = str(int(scalar[seg_index])) if not label_value in labels: labels[label_value] = [] if not i in labels[label_value]: # store the unique fiber id for this label labels[label_value].append(i) # now loop through all detected labels for l in labels: new_tracks = [] for t_id in labels[l]: # grab the fiber + scalars current_fiber = tracks[t_id] new_tracks.append(current_fiber) # now store the trk file trk_outputfile = l + '_' + colors[l] + '.trk' nii_outputfile = l + '_' + colors[l] + '.nii.gz' c.info(Colors.YELLOW + ' Creating fiber ROI ' + Colors.PURPLE + trk_outputfile + Colors.YELLOW + '!' + Colors._CLEAR) io.saveTrk(os.path.join(outputs['roi'], trk_outputfile), new_tracks, header, None, True) # also create a roi label volume for this label value c.info(Colors.YELLOW + ' Creating NII ROI ' + Colors.PURPLE + nii_outputfile + Colors.YELLOW + '!' + Colors._CLEAR) cmd = 'ss;' cmd += 'chb-fsstable;' cmd += 'mri_binarize --i ' + outputs[ 'segmentation'] + ' --o ' + os.path.join( outputs['roi'], nii_outputfile) + ' --match ' + l + ' --binval ' + l + ';' self.__logger.debug(cmd) sp = subprocess.Popen(["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout) sp.communicate()
def roi_extract( self, inputs, outputs ): ''' ''' # check if we have all required input data # we need at least: # - outputs['fibers_mapped'] == Track file in T1 space with mapped scalars if not os.path.exists( outputs['fibers_final'] ): c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['fibers_final'] + Colors.RED + ' but we really need it to start with stage 6!!' + Colors._CLEAR ) sys.exit( 2 ) s = io.loadTrk( outputs['fibers_final'] ) tracks = s[0] header = s[1] scalarNames = header['scalar_name'].tolist() labels = {} # check if the segmentation is mapped try: seg_index = scalarNames.index( 'segmentation' ) except: c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + 'segmentation' + Colors.RED + ' as a mapped scalar but we really need it!' ) sys.exit( 2 ) # create the roi subfolder if not os.path.exists( outputs['roi'] ): os.mkdir( outputs['roi'] ) # parse the color table lut = fyborg.colortable.freesurfer.split( '\n' ) colors = {} for color in lut: if not color or color[0] == '#': continue splitted_line = color.split( ' ' ) splitted_line = filter( None, splitted_line ) colors[splitted_line[0]] = splitted_line[1] # loop through tracks for i, t in enumerate( tracks ): tCoordinates = t[0] tScalars = t[1] # grab the scalars for each point for scalar in tScalars: # but only the label value label_value = str( int( scalar[seg_index] ) ) if not label_value in labels: labels[label_value] = [] if not i in labels[label_value]: # store the unique fiber id for this label labels[label_value].append( i ) # now loop through all detected labels for l in labels: new_tracks = [] for t_id in labels[l]: # grab the fiber + scalars current_fiber = tracks[t_id] new_tracks.append( current_fiber ) # now store the trk file trk_outputfile = l + '_' + colors[l] + '.trk' nii_outputfile = l + '_' + colors[l] + '.nii' c.info( Colors.YELLOW + ' Creating fiber ROI ' + Colors.PURPLE + trk_outputfile + Colors.YELLOW + '!' + Colors._CLEAR ) io.saveTrk( os.path.join( outputs['roi'], trk_outputfile ), new_tracks, header, None, True ) # also create a roi label volume for this label value c.info( Colors.YELLOW + ' Creating NII ROI ' + Colors.PURPLE + nii_outputfile + Colors.YELLOW + '!' + Colors._CLEAR ) cmd = 'ss;' cmd += 'chb-fsstable;' cmd += 'mri_binarize --i ' + outputs['segmentation'] + ' --o ' + os.path.join( outputs['roi'], nii_outputfile ) + ' --match ' + l + ' --binval ' + l + ';' self.__logger.debug( cmd ) sp = subprocess.Popen( ["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout ) sp.communicate()
def connectivity(self, inputs, outputs, cortex_only): ''' Generate connectivity matrices using mapped values. ''' # check if we have all required input data # we need at least: # - outputs['fibers_mapped'] == Track file in T1 space with mapped scalars if not os.path.exists(outputs['fibers_final']): c.error(Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['fibers_final'] + Colors.RED + ' but we really need it to start with stage 5!!' + Colors._CLEAR) sys.exit(2) s = io.loadTrk(outputs['fibers_final']) tracks = s[0] header = s[1] scalarNames = header['scalar_name'].tolist() matrix = {} indices = {} # check if the segmentation is mapped try: indices['segmentation'] = scalarNames.index('segmentation') except: c.error(Colors.RED + 'Could not find ' + Colors.YELLOW + 'segmentation' + Colors.RED + ' as a mapped scalar but we really need it!') sys.exit(2) if cortex_only: labels = [ 2012, 2019, 2032, 2014, 2020, 2018, 2027, 2028, 2003, 2024, 2017, 2026, 2002, 2023, 2010, 2022, 2031, 2029, 2008, 2025, 2005, 2021, 2011, 2013, 2007, 2016, 2006, 2033, 2009, 2015, 2001, 2030, 2034, 2035, 1012, 1019, 1032, 1014, 1020, 1018, 1027, 1028, 1003, 1024, 1017, 1026, 1002, 1023, 1010, 1022, 1031, 1029, 1008, 1025, 1005, 1021, 1011, 1013, 1007, 1016, 1006, 1033, 1009, 1015, 1001, 1030, 1034, 1035 ] else: labels = [ 2012, 2019, 2032, 2014, 2020, 2018, 2027, 2028, 2003, 2024, 2017, 2026, 2002, 2023, 2010, 2022, 2031, 2029, 2008, 2025, 2005, 2021, 2011, 2013, 2007, 2016, 2006, 2033, 2009, 2015, 2001, 2030, 2034, 2035, 49, 50, 51, 52, 58, 53, 54, 1012, 1019, 1032, 1014, 1020, 1018, 1027, 1028, 1003, 1024, 1017, 1026, 1002, 1023, 1010, 1022, 1031, 1029, 1008, 1025, 1005, 1021, 1011, 1013, 1007, 1016, 1006, 1033, 1009, 1015, 1001, 1030, 1034, 1035, 10, 11, 12, 13, 26, 17, 18, 16 ] c.info( Colors.YELLOW + ' Getting ready to create connectivity matrices for the following labels: ' + Colors.PURPLE + str(labels) + Colors._CLEAR) c.info( Colors.YELLOW + ' Note: Mapped scalar values along the points will be averaged for each fiber track.' + Colors._CLEAR) # create matrices for the attached scalars for i, s in enumerate(scalarNames): if i >= header['n_scalars']: break if not s or s == 'segmentation': continue # this is a scalar value for which a matrix will be created matrix[s] = np.zeros([len(labels), len(labels)]) indices[s] = scalarNames.index(s) c.info(Colors.YELLOW + ' Preparing matrix (' + Colors.PURPLE + '[' + str(len(labels)) + 'x' + str(len(labels)) + ']' + Colors.YELLOW + ') for ' + Colors.PURPLE + s + Colors.YELLOW + ' values!' + Colors._CLEAR) if s == 'adc': s = 'inv_adc' matrix[s] = np.zeros([len(labels), len(labels)]) indices[s] = scalarNames.index('adc') c.info(Colors.YELLOW + ' Preparing matrix (' + Colors.PURPLE + '[' + str(len(labels)) + 'x' + str(len(labels)) + ']' + Colors.YELLOW + ') for ' + Colors.PURPLE + s + Colors.YELLOW + ' values!' + Colors._CLEAR) # always create one for the fiber counts matrix['fibercount'] = np.zeros([len(labels), len(labels)]) indices['fibercount'] = 0 c.info(Colors.YELLOW + ' Preparing matrix (' + Colors.PURPLE + '[' + str(len(labels)) + 'x' + str(len(labels)) + ']' + Colors.YELLOW + ') for ' + Colors.PURPLE + 'fibercount' + Colors.YELLOW + ' values!' + Colors._CLEAR) c.info(Colors.YELLOW + ' Analyzing fibers of ' + Colors.PURPLE + os.path.split(outputs['fibers_final'])[1] + Colors.YELLOW + '..' + Colors._CLEAR) for tCounter, t in enumerate(tracks): tCoordinates = t[0] tScalars = t[1] # find the segmentation labels for the start and end points start_label = tScalars[0, indices['segmentation']] end_label = tScalars[-1, indices['segmentation']] try: # now grab the index of the labels in our label list start_index = labels.index(start_label) end_index = labels.index(end_label) except: # this label is not monitored, so ignore this track continue # loop through all different scalars for m in matrix: # calculate the mean for each track value = np.mean(tScalars[:, indices[m]]) if m == 'inv_adc': # invert the value since it is 1-ADC value = 1 / value elif m == 'fibercount': # in the case of fibercount, add 1 value = 1 # store value in the matrix matrix[m][start_index, end_index] += value if not start_index == end_index: matrix[m][end_index, start_index] += value # fiber loop is done, all values are stored # now normalize the matrices np.seterr(all='ignore') # avoid div by 0 warnings cbar = None for m in matrix: if not m == 'fibercount': # normalize it matrix[m][:] /= matrix['fibercount'] matrix[m] = np.nan_to_num(matrix[m]) # store the matrix c.info(Colors.YELLOW + ' Storing ' + Colors.PURPLE + m + Colors.YELLOW + ' connectivity matrix as ' + Colors.PURPLE + os.path.split(outputs['matrix_' + m])[1] + Colors.YELLOW + '!' + Colors._CLEAR) np.savetxt(outputs['matrix_' + m], matrix[m], delimiter='\t') # store a picture picture_path = os.path.splitext( os.path.split(outputs['matrix_' + m])[1])[0] + '.png' c.info(Colors.YELLOW + ' Generating ' + Colors.PURPLE + m + ' image' + Colors.YELLOW + ' as ' + Colors.PURPLE + picture_path + Colors.YELLOW + '!' + Colors._CLEAR) img = plot.imshow(matrix[m], interpolation='nearest') img.set_cmap('jet') img.set_norm(LogNorm()) img.axes.get_xaxis().set_visible(False) img.axes.get_yaxis().set_visible(False) if not cbar: cbar = plot.colorbar() cbar.set_label(m) cbar.set_ticks([]) plot.savefig( os.path.join( os.path.split(outputs['matrix_' + m])[0], picture_path)) np.seterr(all='warn') # reactivate div by 0 warnings # now store the matlab version as well c.info(Colors.YELLOW + ' Storing ' + Colors.PURPLE + 'matlab data bundle' + Colors.YELLOW + ' containing ' + Colors.PURPLE + 'all matrices' + Colors.YELLOW + ' as ' + Colors.PURPLE + os.path.split(outputs['matrix_all'])[1] + Colors.YELLOW + '!' + Colors._CLEAR) scipy.io.savemat(outputs['matrix_all'], matrix, oned_as='row')
def connectivity( self, inputs, outputs, cortex_only ): ''' Generate connectivity matrices using mapped values. ''' # check if we have all required input data # we need at least: # - outputs['fibers_mapped'] == Track file in T1 space with mapped scalars if not os.path.exists( outputs['fibers_final'] ): c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['fibers_final'] + Colors.RED + ' but we really need it to start with stage 5!!' + Colors._CLEAR ) sys.exit( 2 ) s = io.loadTrk( outputs['fibers_final'] ) tracks = s[0] header = s[1] scalarNames = header['scalar_name'].tolist() matrix = {} indices = {} # check if the segmentation is mapped try: indices['segmentation'] = scalarNames.index( 'segmentation' ) except: c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + 'segmentation' + Colors.RED + ' as a mapped scalar but we really need it!' ) sys.exit( 2 ) if cortex_only: labels = [2012, 2019, 2032, 2014, 2020, 2018, 2027, 2028, 2003, 2024, 2017, 2026, 2002, 2023, 2010, 2022, 2031, 2029, 2008, 2025, 2005, 2021, 2011, 2013, 2007, 2016, 2006, 2033, 2009, 2015, 2001, 2030, 2034, 2035, 1012, 1019, 1032, 1014, 1020, 1018, 1027, 1028, 1003, 1024, 1017, 1026, 1002, 1023, 1010, 1022, 1031, 1029, 1008, 1025, 1005, 1021, 1011, 1013, 1007, 1016, 1006, 1033, 1009, 1015, 1001, 1030, 1034, 1035] else: labels = [2012, 2019, 2032, 2014, 2020, 2018, 2027, 2028, 2003, 2024, 2017, 2026, 2002, 2023, 2010, 2022, 2031, 2029, 2008, 2025, 2005, 2021, 2011, 2013, 2007, 2016, 2006, 2033, 2009, 2015, 2001, 2030, 2034, 2035, 49, 50, 51, 52, 58, 53, 54, 1012, 1019, 1032, 1014, 1020, 1018, 1027, 1028, 1003, 1024, 1017, 1026, 1002, 1023, 1010, 1022, 1031, 1029, 1008, 1025, 1005, 1021, 1011, 1013, 1007, 1016, 1006, 1033, 1009, 1015, 1001, 1030, 1034, 1035, 10, 11, 12, 13, 26, 17, 18, 16] c.info( Colors.YELLOW + ' Getting ready to create connectivity matrices for the following labels: ' + Colors.PURPLE + str( labels ) + Colors._CLEAR ) c.info( Colors.YELLOW + ' Note: Mapped scalar values along the points will be averaged for each fiber track.' + Colors._CLEAR ) # create matrices for the attached scalars for i, s in enumerate( scalarNames ): if i >= header['n_scalars']: break if not s or s == 'segmentation': continue # this is a scalar value for which a matrix will be created matrix[s] = np.zeros( [len( labels ), len( labels )] ) indices[s] = scalarNames.index( s ) c.info( Colors.YELLOW + ' Preparing matrix (' + Colors.PURPLE + '[' + str( len( labels ) ) + 'x' + str( len( labels ) ) + ']' + Colors.YELLOW + ') for ' + Colors.PURPLE + s + Colors.YELLOW + ' values!' + Colors._CLEAR ) if s == 'adc': s = 'inv_adc' matrix[s] = np.zeros( [len( labels ), len( labels )] ) indices[s] = scalarNames.index( 'adc' ) c.info( Colors.YELLOW + ' Preparing matrix (' + Colors.PURPLE + '[' + str( len( labels ) ) + 'x' + str( len( labels ) ) + ']' + Colors.YELLOW + ') for ' + Colors.PURPLE + s + Colors.YELLOW + ' values!' + Colors._CLEAR ) # always create one for the fiber counts matrix['fibercount'] = np.zeros( [len( labels ), len( labels )] ) indices['fibercount'] = 0 c.info( Colors.YELLOW + ' Preparing matrix (' + Colors.PURPLE + '[' + str( len( labels ) ) + 'x' + str( len( labels ) ) + ']' + Colors.YELLOW + ') for ' + Colors.PURPLE + 'fibercount' + Colors.YELLOW + ' values!' + Colors._CLEAR ) c.info( Colors.YELLOW + ' Analyzing fibers of ' + Colors.PURPLE + os.path.split( outputs['fibers_final'] )[1] + Colors.YELLOW + '..' + Colors._CLEAR ) for tCounter, t in enumerate( tracks ): tCoordinates = t[0] tScalars = t[1] # find the segmentation labels for the start and end points start_label = tScalars[0, indices['segmentation']] end_label = tScalars[-1, indices['segmentation']] try: # now grab the index of the labels in our label list start_index = labels.index( start_label ) end_index = labels.index( end_label ) except: # this label is not monitored, so ignore this track continue # loop through all different scalars for m in matrix: # calculate the mean for each track value = np.mean( tScalars[:, indices[m]] ) if m == 'inv_adc': # invert the value since it is 1-ADC value = 1 / value elif m == 'fibercount': # in the case of fibercount, add 1 value = 1 # store value in the matrix matrix[m][start_index, end_index] += value if not start_index == end_index: matrix[m][end_index, start_index] += value # fiber loop is done, all values are stored # now normalize the matrices np.seterr( all='ignore' ) # avoid div by 0 warnings cbar = None for m in matrix: if not m == 'fibercount': # normalize it matrix[m][:] /= matrix['fibercount'] matrix[m] = np.nan_to_num( matrix[m] ) # store the matrix c.info( Colors.YELLOW + ' Storing ' + Colors.PURPLE + m + Colors.YELLOW + ' connectivity matrix as ' + Colors.PURPLE + os.path.split( outputs['matrix_' + m] )[1] + Colors.YELLOW + '!' + Colors._CLEAR ) np.savetxt( outputs['matrix_' + m], matrix[m], delimiter='\t' ) # store a picture picture_path = os.path.splitext( os.path.split( outputs['matrix_' + m] )[1] )[0] + '.png' c.info( Colors.YELLOW + ' Generating ' + Colors.PURPLE + m + ' image' + Colors.YELLOW + ' as ' + Colors.PURPLE + picture_path + Colors.YELLOW + '!' + Colors._CLEAR ) img = plot.imshow( matrix[m], interpolation='nearest' ) img.set_cmap( 'jet' ) img.set_norm( LogNorm() ) img.axes.get_xaxis().set_visible( False ) img.axes.get_yaxis().set_visible( False ) if not cbar: cbar = plot.colorbar() cbar.set_label( m ) cbar.set_ticks( [] ) plot.savefig( os.path.join( os.path.split( outputs['matrix_' + m] )[0], picture_path ) ) np.seterr( all='warn' ) # reactivate div by 0 warnings # now store the matlab version as well c.info( Colors.YELLOW + ' Storing ' + Colors.PURPLE + 'matlab data bundle' + Colors.YELLOW + ' containing ' + Colors.PURPLE + 'all matrices' + Colors.YELLOW + ' as ' + Colors.PURPLE + os.path.split( outputs['matrix_all'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR ) scipy.io.savemat( outputs['matrix_all'], matrix, oned_as='row' )