def transform( tracks, matrix, outputFile=None, verbose=False, threadName='Global' ): ''' ''' # O(Tracks x Points) # # loop through all tracks and transform'em!! for t in xrange( len( tracks ) ): track = tracks[t] points = track[0] newPoints = numpy.copy( points ) # loop through all points of the current track for p in xrange( len( points ) ): pointBefore = points[p] pointAfter = numpy.append( pointBefore, 1 ) pointAfter = numpy.dot( matrix, pointAfter ) pointAfter = numpy.delete( pointAfter, -1 ) newPoints[p] = pointAfter # create a new track with the transformed points newTrack = ( newPoints, track[1], track[2] ) # replace the old track with the newTrack tracks[t] = newTrack if not outputFile: return tracks else: # write it out to disk io.saveTrk( outputFile, tracks, None, None, True )
def clearScalars( trkFile1, outputFile ): ''' Copy scalars from trkFile1 to trkFile2 ''' s = io.loadTrk( trkFile1 ) tracks = s[0] origHeader = s[1] tracksHeader = numpy.copy( s[1] ) newTracks = [] for tCounter, t in enumerate( tracks ): tCoordinates = t[0] tScalars = t[1] tProperties = t[2] # clear scalars newTracks.append( ( tCoordinates, None, tProperties ) ) # write trkFile2 with update scalars io.saveTrk( outputFile, newTracks, tracksHeader, None, True ) c.info( 'Cleared scalars from ' + trkFile1 + ' and saved as ' + outputFile )
def sub(master, tracks, outputFile=None, verbose=False, threadName="Global"): """ Subtract tracks from master. Both parameters are nibabel.trackvis.streamlines objects. Calculation cost: O(M*N) Returns the result as a nibabel.trackvis.streamlines object or writes it to the file system if an outputFile is specified. """ masterSizeBefore = len(master) subtractedCount = 0 # O(M*N) for t in xrange(masterSizeBefore): if subtractedCount == len(tracks): # no way we can subtract more.. stop the loop return master c.debug( threadName + ": Looking for more tracks to subtract.. [Check #" + str(t) + "/" + str(masterSizeBefore) + "]", verbose, ) if master[t] == -1: # this fiber was already removed, skip to next one continue for u in xrange(len(tracks)): if tracks[u] == -1: # this fiber was already removed, skip to next one continue # compare fiber if [p for points in master[t][0] for p in points] == [p for points in tracks[u][0] for p in points]: # fibers are equal, set them as dirty master[t] = -1 tracks[u] = -1 subtractedCount += 1 # ... and jump out break master = filter(lambda t: t != -1, master) if not outputFile: return master else: # write it out to disk io.saveTrk(outputFile, master, None, None, True)
def sub(master, tracks, outputFile=None, verbose=False, threadName='Global'): ''' Subtract tracks from master. Both parameters are nibabel.trackvis.streamlines objects. Calculation cost: O(M*N) Returns the result as a nibabel.trackvis.streamlines object or writes it to the file system if an outputFile is specified. ''' masterSizeBefore = len(master) subtractedCount = 0 # O(M*N) for t in xrange(masterSizeBefore): if subtractedCount == len(tracks): # no way we can subtract more.. stop the loop return master c.debug( threadName + ': Looking for more tracks to subtract.. [Check #' + str(t) + '/' + str(masterSizeBefore) + ']', verbose) if master[t] == -1: # this fiber was already removed, skip to next one continue for u in xrange(len(tracks)): if tracks[u] == -1: # this fiber was already removed, skip to next one continue # compare fiber if [p for points in master[t][0] for p in points ] == [p for points in tracks[u][0] for p in points]: # fibers are equal, set them as dirty master[t] = -1 tracks[u] = -1 subtractedCount += 1 # ... and jump out break master = filter(lambda t: t != -1, master) if not outputFile: return master else: # write it out to disk io.saveTrk(outputFile, master, None, None, True)
def createSampleTrkFile( outputfile ): ''' Create a sample track file which contains fibers with random points. The fiber coordinates match the sample volume from above. ''' fibers = [] numberOfFibers = NUMBER_OF_FIBERS print Colors.PURPLE + 'Creating a sample trkFile (' + Colors.CYAN + str( numberOfFibers ) + ' fibers' + Colors.PURPLE + '): ' + Colors.ORANGE + outputfile + Colors.PURPLE + '..' + Colors._CLEAR for f in range( numberOfFibers ): # from 3 to 10 points, randomly chosen numberOfPoints = random.randint( 3, 10 ) # the point array reserves 3 components for each point (x,y,z) points = numpy.empty( shape=( numberOfPoints, 3 ), dtype=numpy.float32 ) for p in range( numberOfPoints ): # create random points with coordinates in the range 0..9 to match the sample volume's dimensions points[p] = [random.randint( 0, int( SAMPLE_VOLUME_DIMENSION_X * SAMPLE_VOLUME_SPACING_X ) - 1 ), random.randint( 0, int( SAMPLE_VOLUME_DIMENSION_Y * SAMPLE_VOLUME_SPACING_Y ) - 1 ), random.randint( 0, int( SAMPLE_VOLUME_DIMENSION_Z * SAMPLE_VOLUME_SPACING_Z ) - 1 )] # create an appropriate header header = eH() header['voxel_size'] = ( SAMPLE_VOLUME_SPACING_X, SAMPLE_VOLUME_SPACING_Y, SAMPLE_VOLUME_SPACING_Z ) header['dim'] = ( SAMPLE_VOLUME_DIMENSION_X, SAMPLE_VOLUME_DIMENSION_Y, SAMPLE_VOLUME_DIMENSION_Z ) # store the trk file fibers.append( ( points, None, None ) ) io.saveTrk( outputfile, fibers, header, None, True ) return numberOfFibers
def copyScalars( trkFile1, trkFile2, outputFile ): ''' Copy scalars from trkFile1 to trkFile2 ''' s = io.loadTrk( trkFile1 ) s2 = io.loadTrk( trkFile2 ) tracks = s[0] tracks2 = s2[0] origHeader = s[1] origHeader2 = s2[1] tracksHeader = numpy.copy( s[1] ) tracksHeader2 = numpy.copy( s2[1] ) #if tracksHeader['n_count'] != tracksHeader2['n_count']: # c.error( 'The track counts do not match!' ) # sys.exit( 2 ) # now copy tracksHeader2['n_scalars'] = tracksHeader['n_scalars'] tracksHeader2['scalar_name'] = tracksHeader['scalar_name'] newTracks2 = [] for tCounter, t in enumerate( tracks ): tCoordinates = t[0] tScalars = t[1] # copy scalars over #tracks2[tCounter][1] = numpy.copy( tScalars ) newTracks2.append( ( tracks2[tCounter][0], tScalars[:], tracks2[tCounter][2] ) ) # write trkFile2 with update scalars io.saveTrk( outputFile, newTracks2, tracksHeader2, None, True ) c.info( 'Copied Scalars from ' + trkFile1 + ' to ' + trkFile2 + ' and saved as ' + outputFile )
# convert to ijk ijkCoords = [x / y for x, y in zip(_current, imageSpacing)] # convert to ijk ijkCoords1 = [max(1, x) for x in ijkCoords] # make larger than 1 ijkCoords2 = [max(0, x) for x in ijkCoords] # make positive # grab value value = image[int(ijkCoords[0]), int(ijkCoords[1]), int(ijkCoords[2])] value1 = image[ijkCoords1[0], ijkCoords1[1], ijkCoords1[2]] value2 = image[int(ijkCoords2[0]), int(ijkCoords2[1]), int(ijkCoords2[2])] print 'value (untouched)', value print 'value (>1)', value1 print 'value (>0)', value2 valueSum += value _last = _current print 'valueSum', valueSum print 'valueMean', valueSum / len(coords) print singleTrack print 'length', "%.100f" % length io.saveTrk('/chb/tmp/nico.trk', [singleTrack], origHeader, None, True)
def run(self, input, output, mode, verbose, jobs): if len(input) < 2: c.error("Please specify at least two *.trk files as input!") sys.exit(2) if os.path.exists(output): # abort if file already exists c.error("File " + str(output) + " already exists..") c.error("Aborting..") sys.exit(2) jobs = int(jobs) if jobs < 1 or jobs > 32: jobs = 1 # load 'master' mTracks = io.loadTrk(input[0]) # copy the tracks and the header from the 'master' c.info("Master is " + input[0]) outputTracks = mTracks[0] c.info("Number of tracks: " + str(len(outputTracks))) header = mTracks[1] # remove the first input input.pop(0) if mode == "add": # # ADD # for i in input: iTracks = io.loadTrk(i) # add the tracks c.debug("Adding " + str(len(iTracks[0])) + " tracks from " + i + " to master..", verbose) outputTracks = TrackvisCalcLogic.add(outputTracks, iTracks[0]) c.debug("Number of output tracks after final addition: " + str(len(outputTracks)), verbose) elif mode == "sub": # # SUB # c.debug("Using " + str(jobs) + " threads..", verbose) mergedOutputTracks = outputTracks[:] for i in input: iTracks = io.loadTrk(i) # subtract the tracks c.info("Subtracting " + i + " (" + str(len(iTracks[0])) + " tracks) from master..") # # THREADED COMPONENT # numberOfThreads = jobs c.info("Splitting master into " + str(jobs) + " pieces..") splittedOutputTracks = u.split_list(mergedOutputTracks, numberOfThreads) # list of threads t = [None] * numberOfThreads # list of alive flags a = [None] * numberOfThreads # list of tempFiles f = [None] * numberOfThreads for n in xrange(numberOfThreads): # mark thread as alive a[n] = True # fire the thread and give it a filename based on the number tmpFile = tempfile.mkstemp(".trk", "t_calc")[1] f[n] = tmpFile t[n] = Process( target=TrackvisCalcLogic.sub, args=(splittedOutputTracks[n][:], iTracks[0][:], tmpFile, verbose, "Thread-" + str(n + 1)), ) c.info("Starting Thread-" + str(n + 1) + "...") t[n].start() allDone = False while not allDone: time.sleep(1) for n in xrange(numberOfThreads): a[n] = t[n].is_alive() if not any(a): # if no thread is alive allDone = True # # END OF THREADED COMPONENT # c.info("All Threads done!") c.info("Merging output..") # now read all the created tempFiles and merge'em to one # first thread output is the master here tmpMaster = f[0] tMasterTracks = io.loadTrk(tmpMaster) for tmpFileNo in xrange(1, len(f)): tTracks = io.loadTrk(f[tmpFileNo]) # add them mergedOutputTracks = TrackvisCalcLogic.add(tMasterTracks[0], tTracks[0]) c.info("Merging done!") # some stats c.info("Number of output tracks after final removal: " + str(len(mergedOutputTracks))) outputTracks = mergedOutputTracks # now save the outputTracks io.saveTrk(output, outputTracks, header) c.info("All done!")
save_image(img, volFile) # trk file fibers = [] # 2,5,6 # 3,5,7 # 2,6,7 # 8,7,3 # 9,5,4 points = np.array([[2, 5, 6], [3, 5, 7], [2, 6, 7], [8, 7, 3], [9, 5, 4]], dtype=np.float32) fibers.append((points, None, None)) io.saveTrk(trkFile, fibers, None, None, True) # with fyborg fyborg.fyborg(trkFile, mappedTrkFile, [fyborg.FyMapAction('test', volFile)]) # now validate s = io.loadTrk(mappedTrkFile) tracks = s[0] origHeader = s[1] scalars = tracks[0][1] print scalars[0], '==', testArr[2][5][6] print scalars[1], '==', testArr[3][5][7] print scalars[2], '==', testArr[2][6][7] print scalars[3], '==', testArr[8][7][3] print scalars[4], '==', testArr[9][5][4]
def run( self, input, output, matrix, jobs ): ''' ''' if os.path.exists( output ): # abort if file already exists c.error( 'File ' + str( output ) + ' already exists..' ) c.error( 'Aborting..' ) sys.exit( 2 ) if not os.path.isfile( matrix ): # abort if the matrix does not exist c.error( 'Matrix-File ' + str( matrix ) + ' does not exist..' ) c.error( 'Aborting..' ) sys.exit( 2 ) jobs = int( jobs ) if jobs < 1 or jobs > 32: jobs = 1 # read c.info( 'Loading ' + input + '..' ) t = io.loadTrk( input ) tracks = t[0] header = t[1] #.. copy the current header newHeader = numpy.copy( header ) # print old matrix in header # # WARNING: this matrix is actually never used by TrackVis (see email from Ruopeng). # We still modify it to keep it in sync with the transformations which we apply point wise. # if hasattr( header, 'vox_to_ras' ): oldMatrix = header['vox_to_ras'] c.info( 'Old transformation matrix:' ) c.info( ' ' + str( oldMatrix[0] ) ) c.info( ' ' + str( oldMatrix[1] ) ) c.info( ' ' + str( oldMatrix[2] ) ) c.info( ' ' + str( oldMatrix[3] ) ) # # load our transformation Matrix # newMatrix = numpy.loadtxt( matrix, float, '#', ' ' ) # # THREADED COMPONENT # numberOfThreads = jobs c.info( 'Splitting the input into ' + str( jobs ) + ' pieces..' ) splittedOutputTracks = u.split_list( tracks, numberOfThreads ) # list of threads t = [None] * numberOfThreads # list of alive flags a = [None] * numberOfThreads # list of tempFiles f = [None] * numberOfThreads for n in xrange( numberOfThreads ): # mark thread as alive a[n] = True # fire the thread and give it a filename based on the number tmpFile = tempfile.mkstemp( '.trk', 't_transform' )[1] f[n] = tmpFile t[n] = Process( target=TrackvisTransformLogic.transform, args=( splittedOutputTracks[n][:], newMatrix, tmpFile, False, 'Thread-' + str( n + 1 ) ) ) c.info( "Starting Thread-" + str( n + 1 ) + "..." ) t[n].start() allDone = False while not allDone: time.sleep( 1 ) for n in xrange( numberOfThreads ): a[n] = t[n].is_alive() if not any( a ): # if no thread is alive allDone = True # # END OF THREADED COMPONENT # c.info( "All Threads done!" ) c.info( "Merging output.." ) # now read all the created tempFiles and merge'em to one # first thread output is the master here tmpMaster = f[0] tMasterTracks = io.loadTrk( tmpMaster ) for tmpFileNo in xrange( 1, len( f ) ): tTracks = io.loadTrk( f[tmpFileNo] ) # add them tracks = TrackvisCalcLogic.add( tMasterTracks[0], tTracks[0] ) c.info( "Merging done!" ) # # replace the matrix in the header with a transformed one even if it will never be used by TrackVis # if hasattr( header, 'vox_to_ras' ): result = numpy.dot( oldMatrix, newMatrix ) c.info( 'New transformation matrix:' ) c.info( ' ' + str( result[0] ) ) c.info( ' ' + str( result[1] ) ) c.info( ' ' + str( result[2] ) ) c.info( ' ' + str( result[3] ) ) newHeader['vox_to_ras'] = result # write c.info( 'Saving ' + output + '..' ) io.saveTrk( output, tracks, newHeader ) c.info( 'All done!' )
save_image( img, volFile ) # trk file fibers = [] # 2,5,6 # 3,5,7 # 2,6,7 # 8,7,3 # 9,5,4 points = np.array( [[2, 5, 6], [3, 5, 7], [2, 6, 7], [8, 7, 3], [9, 5, 4]], dtype=np.float32 ) fibers.append( ( points, None, None ) ) io.saveTrk( trkFile, fibers, None, None, True ) # with fyborg fyborg.fyborg( trkFile, mappedTrkFile, [fyborg.FyMapAction( 'test', volFile )] ) # now validate s = io.loadTrk( mappedTrkFile ) tracks = s[0] origHeader = s[1] scalars = tracks[0][1] print scalars[0], '==', testArr[2][5][6] print scalars[1], '==', testArr[3][5][7] print scalars[2], '==', testArr[2][6][7] print scalars[3], '==', testArr[8][7][3] print scalars[4], '==', testArr[9][5][4]
def run(self, input, output, mode, verbose, jobs): if len(input) < 2: c.error('Please specify at least two *.trk files as input!') sys.exit(2) if os.path.exists(output): # abort if file already exists c.error('File ' + str(output) + ' already exists..') c.error('Aborting..') sys.exit(2) jobs = int(jobs) if jobs < 1 or jobs > 32: jobs = 1 # load 'master' mTracks = io.loadTrk(input[0]) # copy the tracks and the header from the 'master' c.info('Master is ' + input[0]) outputTracks = mTracks[0] c.info('Number of tracks: ' + str(len(outputTracks))) header = mTracks[1] # remove the first input input.pop(0) if mode == 'add': # # ADD # for i in input: iTracks = io.loadTrk(i) # add the tracks c.debug( 'Adding ' + str(len(iTracks[0])) + ' tracks from ' + i + ' to master..', verbose) outputTracks = TrackvisCalcLogic.add(outputTracks, iTracks[0]) c.debug( 'Number of output tracks after final addition: ' + str(len(outputTracks)), verbose) elif mode == 'sub': # # SUB # c.debug('Using ' + str(jobs) + ' threads..', verbose) mergedOutputTracks = outputTracks[:] for i in input: iTracks = io.loadTrk(i) # subtract the tracks c.info('Subtracting ' + i + ' (' + str(len(iTracks[0])) + ' tracks) from master..') # # THREADED COMPONENT # numberOfThreads = jobs c.info('Splitting master into ' + str(jobs) + ' pieces..') splittedOutputTracks = u.split_list(mergedOutputTracks, numberOfThreads) # list of threads t = [None] * numberOfThreads # list of alive flags a = [None] * numberOfThreads # list of tempFiles f = [None] * numberOfThreads for n in xrange(numberOfThreads): # mark thread as alive a[n] = True # fire the thread and give it a filename based on the number tmpFile = tempfile.mkstemp('.trk', 't_calc')[1] f[n] = tmpFile t[n] = Process(target=TrackvisCalcLogic.sub, args=(splittedOutputTracks[n][:], iTracks[0][:], tmpFile, verbose, 'Thread-' + str(n + 1))) c.info("Starting Thread-" + str(n + 1) + "...") t[n].start() allDone = False while not allDone: time.sleep(1) for n in xrange(numberOfThreads): a[n] = t[n].is_alive() if not any(a): # if no thread is alive allDone = True # # END OF THREADED COMPONENT # c.info("All Threads done!") c.info("Merging output..") # now read all the created tempFiles and merge'em to one # first thread output is the master here tmpMaster = f[0] tMasterTracks = io.loadTrk(tmpMaster) for tmpFileNo in xrange(1, len(f)): tTracks = io.loadTrk(f[tmpFileNo]) # add them mergedOutputTracks = TrackvisCalcLogic.add( tMasterTracks[0], tTracks[0]) c.info("Merging done!") # some stats c.info('Number of output tracks after final removal: ' + str(len(mergedOutputTracks))) outputTracks = mergedOutputTracks # now save the outputTracks io.saveTrk(output, outputTracks, header) c.info('All done!')
# convert to ijk ijkCoords = [x / y for x, y in zip( _current, imageSpacing )] # convert to ijk ijkCoords1 = [max( 1, x ) for x in ijkCoords] # make larger than 1 ijkCoords2 = [max( 0, x ) for x in ijkCoords] # make positive # grab value value = image[int( ijkCoords[0] ), int( ijkCoords[1] ), int( ijkCoords[2] )] value1 = image[ijkCoords1[0], ijkCoords1[1], ijkCoords1[2]] value2 = image[int( ijkCoords2[0] ), int( ijkCoords2[1] ), int( ijkCoords2[2] )] print 'value (untouched)', value print 'value (>1)', value1 print 'value (>0)', value2 valueSum += value _last = _current print 'valueSum', valueSum print 'valueMean', valueSum / len( coords ) print singleTrack print 'length', "%.100f" % length io.saveTrk( '/chb/tmp/nico.trk', [singleTrack], origHeader, None, True )
def fyborg( trkFile, outputTrkFile, actions, *args ): if not actions: c.error( "We gotta do something.." ) return showDebug = 'debug' in args singleThread = 'singlethread' in args c.debug( "trkFile:" + str( trkFile ), showDebug ) c.debug( "outputTrkFile:" + str( outputTrkFile ), showDebug ) c.debug( "args:" + str( args ), showDebug ) # load trk file s = io.loadTrk( trkFile ) tracks = s[0] origHeader = s[1] tracksHeader = numpy.copy( s[1] ) numberOfScalars = origHeader['n_scalars'] scalars = origHeader['scalar_name'].tolist() numberOfTracks = origHeader['n_count'] # show some file informations printTrkInfo( tracksHeader, trkFile ) # grab the scalarNames scalarNames = [] for a in actions: if a.scalarName() != FyAction.NoScalar: scalarNames.append( a.scalarName() ) # increase the number of scalars tracksHeader['n_scalars'] += len( scalarNames ) # .. attach the new scalar names for i in range( len( scalarNames ) ): tracksHeader['scalar_name'][numberOfScalars + i] = scalarNames[i] # # THREADED COMPONENT # if singleThread: numberOfThreads = 1 else: numberOfThreads = multiprocessing.cpu_count() c.info( 'Splitting master into ' + str( numberOfThreads ) + ' pieces..' ) splittedOutputTracks = u.split_list( tracks[:], numberOfThreads ) # list of threads t = [None] * numberOfThreads # list of alive flags a = [None] * numberOfThreads # list of tempFiles f = [None] * numberOfThreads for n in xrange( numberOfThreads ): # configure actions __actions = [] for act in actions: __actions.append( act ) # mark thread as alive a[n] = True # fire the thread and give it a filename based on the number tmpFile = tempfile.mkstemp( '.trk', 'fyborg' )[1] f[n] = tmpFile t[n] = Process( target=fyborgLooper_, args=( splittedOutputTracks[n][:], tracksHeader, tmpFile, __actions, showDebug, n + 1 ) ) c.info( "Starting Thread-" + str( n + 1 ) + "..." ) t[n].start() allDone = False while not allDone: time.sleep( 1 ) for n in xrange( numberOfThreads ): a[n] = t[n].is_alive() if not any( a ): # if no thread is alive allDone = True # # END OF THREADED COMPONENT # c.info( "All Threads done!" ) # # Merging stage # c.info( "Merging tracks.." ) outputTracks = [] # now read all the created tempFiles and merge'em to one for tmpFileNo in xrange( 0, len( f ) ): tTracks = io.loadTrk( f[tmpFileNo] ) # add them outputTracks.extend( tTracks[0] ) c.info( "Merging done!" ) io.saveTrk( outputTrkFile, outputTracks, tracksHeader, None, True ) c.info( "All done!" )
def fyborgLooper_( tracks, tracksHeader, outputTrkFile, actions, showDebug, threadNumber ): import numpy numberOfTracks = len( tracks ) # the buffer for the new tracks newTracks = [] # now loop through the tracks for tCounter, t in enumerate( tracks ): # some debug stats c.debug( 'Thread-' + str( threadNumber ) + ': Processing ' + str( tCounter + 1 ) + '/' + str( numberOfTracks ), showDebug ) # generate a unique ID for this track uniqueId = str( threadNumber ) + str( tCounter ) tCoordinates = t[0] tScalars = t[1] # buffer for fiberScalars _fiberScalars = {} # first round: mapping per fiber # .. execute each action and buffer return value (scalar) for a in actions: value = a.scalarPerFiber( uniqueId, tCoordinates, tScalars ) _fiberScalars[a.scalarName()] = value # # Coordinate Loop # # buffer for coordinate scalars) scalars = [] # second round: mapping per coordinate for cCounter, coords in enumerate( tCoordinates ): _coordScalars = {} _mergedScalars = [] # this is the actual buffer for ordered fiber and coord scalars merged together # .. execute each action and buffer return value (scalar) for a in actions: value = a.scalarPerCoordinate( uniqueId, coords[0], coords[1], coords[2] ) # pass x,y,z _coordScalars[a.scalarName()] = value # now merge the old scalars and the fiber and coord scalars # this preserves the ordering of the configured actions if tScalars != None: _mergedScalars.extend( tScalars[cCounter] ) for a in actions: value = _fiberScalars[a.scalarName()] if value != FyAction.NoScalar: _mergedScalars.append( value ) else: # no fiber scalar, check if there is a coord scalar value = _coordScalars[a.scalarName()] if value != FyAction.NoScalar: _mergedScalars.append( value ) # attach scalars scalars.append( _mergedScalars ) # validate the fibers using the action's validate methods validator = [] for a in actions: validator.append( a.validate( uniqueId ) ) if all( validator ): # this is a valid fiber # .. add the new track with the coordinates, the new scalar array and the properties newScalars = numpy.asarray( scalars ) newTracks.append( ( t[0], newScalars, t[2] ) ) # save everything io.saveTrk( outputTrkFile, newTracks, tracksHeader, None, True )