Esempio n. 1
0
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 )
Esempio n. 2
0
File: fy.py Progetto: FNNDSC/fyborg
  def analyze_input_data( self, input_directory, inputs ):
    '''
    Scan an input directory for all kind of inputs. Connectome Pipeline output has 
    higher priority than Tractography Pipeline output since the Connectome pipeline 
    also includes the Tractography output.
    
    Returns a dictionary of found files.
    '''
    for root, dirs, files in os.walk( input_directory ):

      dirs.sort()

      for f in files:
        fullpath = os.path.join( root, f )

        # try to find the files
        for _f in inputs:

          # don't check if we already found this one
          if inputs[_f][-1] != None:
            continue

          for _mask in inputs[_f][:-1]:

            if fnmatch.fnmatch( fullpath, _mask ):
              # this matches our regex
              c.info( Colors.YELLOW + '  Found ' + Colors.PURPLE + f + Colors.YELLOW + '!' + Colors._CLEAR )
              self.__logger.debug( 'Full path: ' + fullpath )
              inputs[_f][-1] = fullpath
              #time.sleep( 1 )
              # don't consider any other option
              break

    return inputs
Esempio n. 3
0
File: fy.py Progetto: FNNDSC/fyborg
  def preprocessing( self, inputs, outputs ):
    '''
    Co-Register the input files using Flirt.
    '''

    # convert the T1.mgz to T1.nii
    cmd = 'ss;'
    cmd += 'chb-fsstable;'
    cmd += 'mri_convert ' + inputs['T1'][-1] + ' ' + outputs['T1']
    c.info( Colors.YELLOW + '  Converting ' + Colors.PURPLE + 'T1.mgz' + Colors.YELLOW + ' to ' + Colors.PURPLE + 'T1.nii' + Colors.YELLOW + '!' + Colors._CLEAR )
    sp = subprocess.Popen( ["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout )
    sp.communicate()

    # convert the aparc+aseg.mgz to aparc+aseg.nii
    cmd = 'ss;'
    cmd += 'chb-fsstable;'
    cmd += 'mri_convert ' + inputs['segmentation'][-1] + ' ' + outputs['segmentation']
    c.info( Colors.YELLOW + '  Converting ' + Colors.PURPLE + 'aparc+aseg.mgz' + Colors.YELLOW + ' to ' + Colors.PURPLE + 'aparc+aseg.nii' + Colors.YELLOW + '!' + Colors._CLEAR )
    sp = subprocess.Popen( ["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout )
    sp.communicate()

    # register B0 to T1
    cmd = 'ss;'
    cmd += 'chb-fsstable;'
    flirtcmd = 'flirt -in ' + inputs['b0'][-1] + ' -ref ' + outputs['T1'] + ' -usesqform -nosearch -dof 6 -cost mutualinfo -out ' + outputs['b0_T1_space'] + '.gz -omat ' + outputs['B0toT1matrix'] + ';'
    cmd += flirtcmd
    cmd += 'gzip -d -f ' + outputs['b0_T1_space'] + '.gz;'
    self.__logger.debug( flirtcmd )
    c.info( Colors.YELLOW + '  Registering ' + Colors.PURPLE + os.path.split( inputs['b0'][-1] )[1] + Colors.YELLOW + ' to ' + Colors.PURPLE + 'T1.nii' + Colors.YELLOW + ' and storing ' + Colors.PURPLE + os.path.split( outputs['B0toT1matrix'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
    sp = subprocess.Popen( ["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout )
    sp.communicate()

    # resample all other DTI volumes to T1 space
    for i in inputs:

      if i == 'fibers' or i == 'segmentation' or i == 'T1' or i == 'b0':
        # we do not map these
        continue

      cmd = 'ss;'
      cmd += 'chb-fsstable;'
      flirtcmd = 'flirt -in ' + inputs[i][-1] + ' -ref ' + outputs['T1'] + ' -out ' + outputs[i + '_T1_space'] + '.gz -init ' + outputs['B0toT1matrix'] + ' -applyxfm;'
      cmd += flirtcmd
      cmd += 'gzip -d -f ' + outputs[i + '_T1_space'] + '.gz;'
      self.__logger.debug( flirtcmd )
      c.info( Colors.YELLOW + '  Resampling ' + Colors.PURPLE + os.path.split( inputs[i][-1] )[1] + Colors.YELLOW + ' as ' + Colors.PURPLE + os.path.split( outputs[i + '_T1_space'] )[1] + Colors.YELLOW + ' using ' + Colors.PURPLE + os.path.split( outputs['B0toT1matrix'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
      sp = subprocess.Popen( ["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout )
      sp.communicate()

    # resample the fibers to T1 space
    cmd = 'ss;'
    cmd += 'chb-fsstable;'
    transformcmd = 'track_transform ' + inputs['fibers'][-1] + ' ' + outputs['fibers'] + ' -src ' + inputs['b0'][-1] + ' -ref ' + outputs['T1'] + ' -reg ' + outputs['B0toT1matrix'] + ';'
    cmd += transformcmd
    self.__logger.debug( transformcmd )
    c.info( Colors.YELLOW + '  Transforming ' + Colors.PURPLE + os.path.split( inputs['fibers'][-1] )[1] + Colors.YELLOW + ' to ' + Colors.PURPLE + os.path.split( outputs['fibers'] )[1] + Colors.YELLOW + ' using ' + Colors.PURPLE + os.path.split( outputs['B0toT1matrix'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
    sp = subprocess.Popen( ["/bin/bash", "-i", "-c", cmd], stdout=sys.stdout )
    sp.communicate()
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
    def aniso2iso(self, image, spacing, dimensions):
        '''
    from dipy.align.aniso2iso
    '''
        header = image.header
        oldspacing = header.get_zooms()
        olddimensions = image.shape[:3]

        if spacing == 'no':
            newspacing = (min(oldspacing), min(oldspacing), min(oldspacing))
        else:
            newspacing = (float(spacing.split(',')[0]),
                          float(spacing.split(',')[1]),
                          float(spacing.split(',')[2]))

        if dimensions == 'no':
            newdimensions = olddimensions
        else:
            newdimensions = (int(dimensions.split(',')[0]),
                             int(dimensions.split(',')[1]),
                             int(dimensions.split(',')[2]))

        c.info('Resampling the master image..')
        c.info('    old spacing ' + str(oldspacing))
        c.info('    old dimensions ' + str(olddimensions))

        # work on a numpy array to resample to isotropic spacing
        R = numpy.diag(numpy.array(newspacing) / numpy.array(oldspacing))
        new_shape = numpy.array(oldspacing) / numpy.array(
            newspacing) * numpy.array(newdimensions)
        new_shape = numpy.round(new_shape).astype('i8')
        newImage = affine_transform(input=image,
                                    matrix=R,
                                    offset=numpy.zeros(3, ),
                                    output_shape=tuple(new_shape),
                                    order=0)
        Rx = numpy.eye(4)
        Rx[:3, :3] = R
        # get the mew world-image matrix
        affine = numpy.dot(image.coordmap.affine, Rx)

        # convert to NiPy image

        # copy the old coordmap and replace the affine matrix
        newCoordMap = image.coordmap
        newCoordMap.affine = affine

        # create a new NiPy image with the resampled data and the new coordmap (including the affine matrix)
        nipyImage = fromarray(newImage, '', '', newCoordMap)

        c.info('    new spacing ' + str(newspacing))
        c.info('    new dimensions ' + str(nipyImage.shape[:3]))

        return nipyImage
Esempio n. 7
0
  def setupGrid( self, matrix ):

    if self.__test:
      self.__rows = 101
      self.__cols = 101

      self.__gridWidget = GridView( self, self.__rows, self.__cols, False )
      self.__layout.addWidget( self.__gridWidget, 0, 0 )

      b_overwriteSpectralValue = True
      maxEnergy = 255 / 3
      automaton = C_spectrum_CAM_RGB( maxQuanta=maxEnergy )
      automaton.component_add( 'R', maxEnergy / 3, b_overwriteSpectralValue )
      automaton.component_add( 'G', maxEnergy / 3, b_overwriteSpectralValue )
      automaton.component_add( 'B', maxEnergy / 3, b_overwriteSpectralValue )
      automaton.updateRule_changeAmount(self.__updateAmount)

      world = C_CAE( np.array( ( self.__rows, self.__cols ) ), automaton )
      world.verbosity_set( 1 )
      arr_world = np.zeros( ( self.__rows, self.__cols ) )
      arr_world[0, 0] = 1
      arr_world[50, 50] = maxEnergy / 3 + 1
      arr_world[100, 100] = maxEnergy / 3 * 2 + 1

    elif matrix:
      maxEnergy = 255

      arr_worldRaw = np.loadtxt( matrix, float, '#', '\t' )
      arr_world = misc.arr_normalize( arr_worldRaw, scale=maxEnergy )

      self.__rows, self.__cols = arr_world.shape

      self.__gridWidget = GridView( self, self.__rows, self.__cols, False )
      self.__layout.addWidget( self.__gridWidget, 0, 0 )

      b_overwriteSpectralValue = True
      automaton = C_spectrum_CAM_RGB( maxQuanta=maxEnergy )
      automaton.component_add( 'R', maxEnergy / 3, b_overwriteSpectralValue )
      automaton.component_add( 'G', maxEnergy / 3, b_overwriteSpectralValue )
      automaton.component_add( 'B', maxEnergy / 3, b_overwriteSpectralValue )
      print "Update amount = %d" % self.__updateAmount
      automaton.updateRule_changeAmount(self.__updateAmount)

      world = C_CAE( np.array( ( self.__rows, self.__cols ) ), automaton )
      world.verbosity_set( 1 )

    else:
      c.error( 'No test mode and no matrix..' )
      sys.exit()

    print arr_world
    world.initialize( arr_world )

    self.__world = world
Esempio n. 8
0
  def onTick( self ):
    '''
    '''
    # update the iterations counter
    self.__iterations += 1
    self.__iterationLabel.setText( 'Iterations: ' + str( self.__iterations ) )
    self.__world.state_transition()

    # draw it
    self.draw()

    b_cornersDominant = False
    if self.__b_stopAtCorners:
        b_cornersDominant = self.__world.currentGridCorners_areAllDominant()

    if self.__iterations >= int( self.__maxIterations ) and \
       int( self.__maxIterations ) != -1                or \
       self.__b_stopAtCorners and b_cornersDominant:

      # max. iterations reached

      self.__timer.stop()
      if self.__b_stopAtCorners: self.__playButton.setText('All corners are active')
      else: self.__playButton.setText( 'Maximum iterations reached' )
      self.__playButton.setEnabled( False )

      if self.__output:
        # take a screenshot and exit
        self.save( self.__output, self.__filestem )
        c.info( 'Took screenshot and saved matrix.')
        c.info( 'Output: ' + str( self.__output ) + os.sep + self.__filestem + '.*)' )
        c.info( 'Number of iterations: %d' % self.__iterations )
        c.info( 'Good-bye!' )
        sys.exit()
Esempio n. 9
0
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 )
Esempio n. 10
0
    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!")
Esempio n. 11
0
def makeMatrix(inputs, outputs, no_cortex):
    """
  Make 1/ADC, ADC, FA, FiberNumber, FiberLength, E1, E2, E3 connectivity matrices.
  """

    s = io.loadTrk(outputs["fibers_final"])
    tracks = s[0]
    header = s[1]

    scalarNames = header["scalar_name"].tolist()
    matrix = {}

    # check if the segmentation is mapped
    try:
        scalarNames.index("segmentation")
    except:
        c.error(Colors.RED)

    for s in scalarNames:

        if not s:
            continue

        print s

    return

    for i in inputs:

        if i == "fibers" or i == "segmentation" or i == "T1" or i == "b0":
            # we do not map these
            continue

    # for tCounter, t in enumerate( tracks ):

    try:
        labelIndex = scalarNames.index("segmentation")
        adcIndex = scalarNames.index("adc")
        faIndex = scalarNames.index("fa")
        e1Index = scalarNames.index("e1")
        e2Index = scalarNames.index("e2")
        e3Index = scalarNames.index("e3")
        lengthIndex = scalarNames.index("length")
    except:
        c.error("Not all scalars were found: aparc_aseg_endlabel, adc, fa, length, e1, e2, e3")
        sys.exit(2)

    m_fn = numpy.zeros([68, 68])
    m_fa = numpy.zeros([68, 68])
    m_adc = numpy.zeros([68, 68])
    m_adcinv = numpy.zeros([68, 68])
    m_len = numpy.zeros([68, 68])
    m_e1 = numpy.zeros([68, 68])
    m_e2 = numpy.zeros([68, 68])
    m_e3 = numpy.zeros([68, 68])

    fslabel_vol = [
        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,
    ]

    for tCounter, t in enumerate(tracks):

        tCoordinates = t[0]
        tScalars = t[1]

        fa = numpy.mean(tScalars[:, faIndex])
        adc = numpy.mean(tScalars[:, adcIndex])
        e1 = numpy.mean(tScalars[:, e1Index])
        e2 = numpy.mean(tScalars[:, e2Index])
        e3 = numpy.mean(tScalars[:, e3Index])
        len = tScalars[0, lengthIndex]

        firstLabel = tScalars[0, labelIndex]
        lastLabel = tScalars[-1, labelIndex]

        try:
            fIndex = fslabel_vol.index(firstLabel)
            lIndex = fslabel_vol.index(lastLabel)
        except:
            continue

        print "found", firstLabel, lastLabel

        m_fn[fIndex, lIndex] += 1
        m_fa[fIndex, lIndex] += fa
        m_adc[fIndex, lIndex] += adc
        m_e1[fIndex, lIndex] += e1
        m_e2[fIndex, lIndex] += e2
        m_e3[fIndex, lIndex] += e3
        m_adcinv[fIndex, lIndex] += 1 / adc
        m_len[fIndex, lIndex] += len

    # symmetrize matrices
    m_fn = m_fn + m_fn.T - numpy.diag(m_fn.diagonal())
    m_fa = m_fa + m_fa.T - numpy.diag(m_fa.diagonal())
    m_adc = m_adc + m_adc.T - numpy.diag(m_adc.diagonal())
    m_e1 = m_e1 + m_e1.T - numpy.diag(m_e1.diagonal())
    m_e2 = m_e2 + m_e2.T - numpy.diag(m_e2.diagonal())
    m_e3 = m_e3 + m_e3.T - numpy.diag(m_e3.diagonal())
    m_adcinv = m_adcinv + m_adcinv.T - numpy.diag(m_adcinv.diagonal())
    m_len = m_len + m_len.T - numpy.diag(m_len.diagonal())

    # normalize matrices
    m_fa[:] /= m_fn[:]
    m_adc[:] /= m_fn[:]
    m_e1[:] /= m_fn[:]
    m_e2[:] /= m_fn[:]
    m_e3[:] /= m_fn[:]
    m_adcinv[:] /= m_fn[:]
    m_len[:] /= m_fn[:]
    m_fa = numpy.nan_to_num(m_fa)
    m_e1 = numpy.nan_to_num(m_e1)
    m_e2 = numpy.nan_to_num(m_e2)
    m_e3 = numpy.nan_to_num(m_e3)
    m_adc = numpy.nan_to_num(m_adc)
    m_adcinv = numpy.nan_to_num(m_adcinv)
    m_len = numpy.nan_to_num(m_len)

    # save as .mat and .csv
    sio.savemat(
        outputDirectory + "fibmap_all_cMatrix.mat",
        {
            "m_fiberNumber": m_fn,
            "m_fa": m_fa,
            "m_adc": m_adc,
            "m_adcInverse": m_adcinv,
            "m_fiberLength": m_len,
            "m_e1": m_e1,
            "m_e2": m_e2,
            "m_e3": m_e3,
        },
    )

    numpy.savetxt(outputDirectory + "fibmap_fibernumber_cMatrix.csv", m_fn, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_fa_cMatrix.csv", m_fa, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_e1_cMatrix.csv", m_e1, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_e2_cMatrix.csv", m_e2, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_e3_cMatrix.csv", m_e3, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_adc_cMatrix.csv", m_adc, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_adcinv_cMatrix.csv", m_adcinv, delimiter=",")
    numpy.savetxt(outputDirectory + "fibmap_fiberlength_cMatrix.csv", m_len, delimiter=",")

    c.info("Connectivity matrices generated and stored.")
Esempio n. 12
0
File: fy.py Progetto: FNNDSC/fyborg
  parser.add_argument( '-co', '--cortex_only', action='store_true', dest='cortex_only', help='Perform filtering for cortex specific analysis and skip sub-cortical structures.' )
  parser.add_argument( '-s', '--stage', action='store', dest='stage', default=0, type=int, help='Start with a specific stage while skipping the ones before. E.g. --stage 3 directly starts the mapping without preprocessing, --stage 4 starts with the filtering' )
  parser.add_argument( '-overwrite', '--overwrite', action='store_true', dest='overwrite', help='Overwrite any existing output. DANGER!!' )
  parser.add_argument( '-v', '--verbose', action='store_true', dest='verbose', help='Show verbose output' )

  # always show the help if no arguments were specified
  if len( sys.argv ) == 1:
    parser.print_help()
    sys.exit( 1 )

  options = parser.parse_args()

  # validate the inputs here
  if not os.path.isdir( options.input ):

    c.error( Colors.RED + 'Could not find the input directory! Specify a valid directory using -i $PATH.' + Colors._CLEAR )
    sys.exit( 2 )

  if os.path.exists( options.output ) and int( options.stage ) == 0:

    if not options.overwrite:
      c.error( Colors.RED + 'The output directory exists! Add --overwrite to erase previous content!' + Colors._CLEAR )
      c.error( Colors.RED + 'Or use --stage > 2 to start with a specific stage which re-uses the previous content..' + Colors._CLEAR )
      sys.exit( 2 )
    else:
      # silently delete the existing output
      shutil.rmtree( options.output )

  if options.stage > 0 and not os.path.exists( options.output ):
    # we start with a specific stage so we need the output stuff
    c.error( Colors.RED + 'The output directory does not exist! We need it when using -s/--stage to resume the process!' + Colors._CLEAR )
Esempio n. 13
0
File: fy.py Progetto: FNNDSC/fyborg
  def run( self, input, output, radius, length, stage, cortex_only, verbose ):
    '''
    '''

    if stage == 0:
      # create output directory
      # but not if we start with a different stage
      os.mkdir( output )

    # activate log file
    self.__debug = verbose
    self.__logger = Logger( os.path.join( output, 'log.txt' ), verbose )
    sys.stdout = self.__logger
    sys.stderr = self.__logger

    # the input data
    _inputs = {'adc':[ '*adc.nii', None],
              'b0':[ '*b0.nii', None],
              'e1':['*e1.nii', None],
              'e2':[ '*e2.nii', None],
              'e3':[ '*e3.nii', None],
              'fa':[ '*fa.nii', None],
              'fibers':['*streamline.trk', '*/final-trackvis/*.trk', None],
              'segmentation': ['*aparc+aseg.mgz', None],
              'T1':['*/mri/brain.mgz', None]
              }

    # the output data
    _outputs = {'T1':os.path.join( output, 'T1.nii' ),
                'segmentation':os.path.join( output, 'aparc+aseg.nii' ),
                'b0_T1_space':os.path.join( output, 'dti_b0_T1_space.nii' ),
                'adc_T1_space':os.path.join( output, 'dti_adc_T1_space.nii' ),
                'fa_T1_space':os.path.join( output, 'dti_fa_T1_space.nii' ),
                'e1_T1_space':os.path.join( output, 'dti_e1_T1_space.nii' ),
                'e2_T1_space':os.path.join( output, 'dti_e2_T1_space.nii' ),
                'e3_T1_space':os.path.join( output, 'dti_e3_T1_space.nii' ),
                'B0toT1matrix':os.path.join( output, 'B0-to-T1.mat' ),
                'fibers':os.path.join( output, 'fybers_T1_space.trk' ),
                'fibers_mapped':os.path.join( output, 'fybers_T1_space_mapped.trk' ),
                'fibers_mapped_length_filtered':os.path.join( output, 'fybers_T1_space_mapped_length_filtered.trk' ),
                'fibers_mapped_length_filtered_cortex_only':os.path.join( output, 'fybers_T1_space_mapped_length_filtered_cortex_only.trk' ),
                'fibers_final':os.path.join( output, 'fybers_final.trk' ),
                'matrix_all': os.path.join( output, 'matrix_all.mat' ),
                'matrix_fibercount': os.path.join( output, 'matrix_fibercount.csv' ),
                'matrix_length': os.path.join( output, 'matrix_length.csv' ),
                'matrix_adc': os.path.join( output, 'matrix_adc.csv' ),
                'matrix_inv_adc': os.path.join( output, 'matrix_inv_adc.csv' ),
                'matrix_fa': os.path.join( output, 'matrix_fa.csv' ),
                'matrix_e1': os.path.join( output, 'matrix_e1.csv' ),
                'matrix_e2': os.path.join( output, 'matrix_e2.csv' ),
                'matrix_e3': os.path.join( output, 'matrix_e3.csv' ),
                'roi':os.path.join( output, 'roi' )
                }

    self.intro()

    # 4 x beep
    print '\a\a\a\a\a\a\a'

    #time.sleep( 3 )

    # stage 1
    c.info( Colors.YELLOW + '>> STAGE [' + Colors.PURPLE + '1' + Colors.YELLOW + ']: ' + Colors.YELLOW + ' ANALYZING INPUT DATA' + Colors._CLEAR )

    if stage <= 2: # we can never skip stage 1 without skipping stage 2
      _inputs = self.analyze_input_data( input, _inputs )
    else:
      c.info( Colors.PURPLE + '  skipping it..' + Colors._CLEAR )

    # stage 2
    c.info( Colors.YELLOW + '>> STAGE [' + Colors.PURPLE + '2' + Colors.YELLOW + ']: ' + Colors.YELLOW + ' PREPROCESSING' + Colors._CLEAR )

    if stage <= 2:
      self.preprocessing( _inputs, _outputs )
    else:
      c.info( Colors.PURPLE + '  skipping it..' + Colors._CLEAR )

    # stage 3
    c.info( Colors.YELLOW + '>> STAGE [' + Colors.PURPLE + '3' + Colors.YELLOW + ']: ' + Colors.YELLOW + ' MAPPING' + Colors._CLEAR )

    if stage <= 3:
      self.mapping( _inputs, _outputs, radius )
    else:
      c.info( Colors.PURPLE + '  skipping it..' + Colors._CLEAR )

    c.info( Colors.YELLOW + '>> STAGE [' + Colors.PURPLE + '4' + Colors.YELLOW + ']: ' + Colors.YELLOW + ' FILTERING' + Colors._CLEAR )

    if stage <= 4:
      self.filtering( _inputs, _outputs, length, cortex_only )
    else:
      c.info( Colors.PURPLE + '  skipping it..' + Colors._CLEAR )

    c.info( Colors.YELLOW + '>> STAGE [' + Colors.PURPLE + '5' + Colors.YELLOW + ']: ' + Colors.YELLOW + ' CONNECTIVITY MATRICES' + Colors._CLEAR )

    if stage <= 5:
      self.connectivity( _inputs, _outputs, cortex_only )
    else:
      c.info( Colors.PURPLE + '  skipping it..' + Colors._CLEAR )

    c.info( Colors.YELLOW + '>> STAGE [' + Colors.PURPLE + '6' + Colors.YELLOW + ']: ' + Colors.YELLOW + ' ROI EXTRACTION' + Colors._CLEAR )

    if stage <= 6:
      self.roi_extract( _inputs, _outputs )
    else:
      c.info( Colors.PURPLE + '  skipping it..' + Colors._CLEAR )



    self.outro()
    c.info( '' )
    c.info( 'ALL DONE! SAYONARA..' )
Esempio n. 14
0
    def run(self, files):
        '''
    '''
        for f in files:

            header = io.loadTrkHeaderOnly(f)
            dimensions = header['dim']
            spacing = header['voxel_size']
            origin = header['origin']
            numberOfScalars = header['n_scalars']
            scalarNames = header['scalar_name']
            numberOfProperties = header['n_properties']
            propertyNames = header['property_name']
            vox2rasMatrix = header['vox_to_ras']
            voxelOrder = header['voxel_order']
            pad1 = header['pad1']
            pad2 = header['pad2']
            imageOrientation = header['image_orientation_patient']
            numberOfTracks = header['n_count']
            version = header['version']

            c.info('FILE: ' + f)

            c.info('  TRACKVIS VERSION: ' + str(version))
            c.info('  NUMBER OF TRACKS: ' + str(numberOfTracks))

            c.info('  DIMENSIONS: ' + str(dimensions))
            c.info('  SPACING: ' + str(spacing))
            c.info('  ORIGIN: ' + str(origin))

            c.info('  NUMBER OF SCALARS: ' + str(numberOfScalars))
            if numberOfScalars > 0:
                c.info('    SCALARS: ' + str(scalarNames))

            c.info('  NUMBER OF PROPERTIES: ' + str(numberOfProperties))
            if numberOfProperties > 0:
                c.info('    PROPERTIES: ' + str(propertyNames))

            if version == 2:
                # only in trackvis v2
                c.info('  VOX2RAS Matrix:')
                c.info('    ' + str(vox2rasMatrix[0]))
                c.info('    ' + str(vox2rasMatrix[1]))
                c.info('    ' + str(vox2rasMatrix[2]))
                c.info('    ' + str(vox2rasMatrix[3]))

            c.info('  VOXEL ORDER: ' + str(voxelOrder))
            #c.info( '  IMAGE ORIENTATION: ' )
            #c.info( '    ' + str( imageOrientation ) )
            #c.info( '  PADDING 1: ' + str( pad1 ) )
            #c.info( '  PADDING 2: ' + str( pad2 ) )

            print
Esempio n. 15
0
  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!' )
Esempio n. 16
0
File: fy.py Progetto: FNNDSC/fyborg
  def mapping( self, inputs, outputs, radius ):
    '''
    Map all detected scalar volumes to each fiber.
    '''
    # check if we have all required input data
    # we need at least: 
    #  - outputs['fibers'] == Track file in T1 space
    #  - outputs['segmentation'] == Label Map
    if not os.path.exists( outputs['fibers'] ):
      c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['fibers'] + Colors.RED + ' but we really need it to start with stage 3!!' + Colors._CLEAR )
      sys.exit( 2 )
    if not os.path.exists( outputs['segmentation'] ):
      c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['segmentation'] + Colors.RED + ' but we really need it to start with stage 3!!' + Colors._CLEAR )
      sys.exit( 2 )

    actions = []

    for i in inputs:

      if i == 'fibers' or i == 'segmentation' or i == 'T1' or i == 'b0':
        # we do not map these
        continue

      if not os.path.exists( outputs[i + '_T1_space'] ):
        # we can't map this since we didn't find the file
        continue

      # for normal scalars: append it to the actions
      actions.append( FyMapAction( i, outputs[i + '_T1_space'] ) )

      c.info( Colors.YELLOW + '  Configuring mapping of ' + Colors.PURPLE + os.path.split( outputs[i + '_T1_space'] )[1] + Colors.YELLOW + ' to ' + Colors.PURPLE + os.path.split( outputs['fibers'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )

    # now the segmentation with the lookaround radius
    actions.append( FyRadiusMapAction( 'segmentation', outputs['segmentation'], radius ) )
    c.info( Colors.YELLOW + '  Configuring mapping of ' + Colors.PURPLE + os.path.split( outputs['segmentation'] )[1] + Colors.YELLOW + ' to ' + Colors.PURPLE + os.path.split( outputs['fibers'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )

    # and also the fiber length
    actions.append( FyLengthAction() )
    c.info( Colors.YELLOW + '  Configuring mapping of ' + Colors.PURPLE + 'fiber length' + Colors.YELLOW + ' to ' + Colors.PURPLE + os.path.split( outputs['fibers'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )

    # run, forest, run!!
    c.info( Colors.YELLOW + '  Performing configured mapping for ' + Colors.PURPLE + os.path.split( outputs['fibers'] )[1] + Colors.YELLOW + ' and storing as ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped'] )[1] + Colors.YELLOW + ' (~ 30 minutes)!' + Colors._CLEAR )
    if self.__debug:
      fyborg.fyborg( outputs['fibers'], outputs['fibers_mapped'], actions, 'debug' )
    else:
      fyborg.fyborg( outputs['fibers'], outputs['fibers_mapped'], actions )
Esempio n. 17
0
  def run( self, files ):
    '''
    '''
    for f in files:

      header = io.loadTrkHeaderOnly( f )
      dimensions = header['dim']
      spacing = header['voxel_size']
      origin = header['origin']
      numberOfScalars = header['n_scalars']
      scalarNames = header['scalar_name']
      numberOfProperties = header['n_properties']
      propertyNames = header['property_name']
      vox2rasMatrix = header['vox_to_ras']
      voxelOrder = header['voxel_order']
      pad1 = header['pad1']
      pad2 = header['pad2']
      imageOrientation = header['image_orientation_patient']
      numberOfTracks = header['n_count']
      version = header['version']

      c.info( 'FILE: ' + f )

      c.info( '  TRACKVIS VERSION: ' + str( version ) )
      c.info( '  NUMBER OF TRACKS: ' + str( numberOfTracks ) )

      c.info( '  DIMENSIONS: ' + str( dimensions ) )
      c.info( '  SPACING: ' + str( spacing ) )
      c.info( '  ORIGIN: ' + str( origin ) )

      c.info( '  NUMBER OF SCALARS: ' + str( numberOfScalars ) )
      if numberOfScalars > 0:
        c.info( '    SCALARS: ' + str( scalarNames ) )

      c.info( '  NUMBER OF PROPERTIES: ' + str( numberOfProperties ) )
      if numberOfProperties > 0:
        c.info( '    PROPERTIES: ' + str( propertyNames ) )

      if version == 2:
        # only in trackvis v2
        c.info( '  VOX2RAS Matrix:' )
        c.info( '    ' + str( vox2rasMatrix[0] ) )
        c.info( '    ' + str( vox2rasMatrix[1] ) )
        c.info( '    ' + str( vox2rasMatrix[2] ) )
        c.info( '    ' + str( vox2rasMatrix[3] ) )

      c.info( '  VOXEL ORDER: ' + str( voxelOrder ) )
      #c.info( '  IMAGE ORIENTATION: ' )
      #c.info( '    ' + str( imageOrientation ) )
      #c.info( '  PADDING 1: ' + str( pad1 ) )
      #c.info( '  PADDING 2: ' + str( pad2 ) )

      print
Esempio n. 18
0
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!" )
Esempio n. 19
0
File: fy.py Progetto: FNNDSC/fyborg
  def filtering( self, inputs, outputs, length, cortex_only ):
    '''
    Filter the mapped fibers.
    '''

    # 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_mapped'] ):
      c.error( Colors.RED + 'Could not find ' + Colors.YELLOW + outputs['fibers_mapped'] + Colors.RED + ' but we really need it to start with stage 4!!' + Colors._CLEAR )
      sys.exit( 2 )

    # find the order of the mapped scalars
    header = io.loadTrkHeaderOnly( outputs['fibers_mapped'] )
    scalars = list( header['scalar_name'] )

    # split the length range
    length = length.split( ' ' )
    min_length = int( length[0] )
    max_length = int( length[1] )

    # length filtering

    c.info( Colors.YELLOW + '  Filtering ' + Colors.PURPLE + 'fiber length' + Colors.YELLOW + ' to be ' + Colors.PURPLE + '>' + str( min_length ) + ' and <' + str( max_length ) + Colors.YELLOW + ' for ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped'] )[1] + Colors.YELLOW + ' and store as ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped_length_filtered'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
    fyborg.fyborg( outputs['fibers_mapped'], outputs['fibers_mapped_length_filtered'], [FyFilterLengthAction( scalars.index( 'length' ), min_length, max_length )] )

    header = io.loadTrkHeaderOnly( outputs['fibers_mapped_length_filtered'] )
    new_count = header['n_count']

    c.info( Colors.YELLOW + '  Number of tracks after ' + Colors.PURPLE + 'length filtering' + Colors.YELLOW + ': ' + str( new_count ) + Colors.YELLOW + Colors._CLEAR )

    if cortex_only:

      # special cortex filtering

      c.info( Colors.YELLOW + '  Filtering for ' + Colors.PURPLE + 'valid cortex structures' + Colors.YELLOW + ' in ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped_length_filtered'] )[1] + Colors.YELLOW + ' and store as ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped_length_filtered_cortex_only'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
      c.info( Colors.PURPLE + '    Conditions for valid fibers:' + Colors._CLEAR )
      c.info( Colors.PURPLE + '    1.' + Colors.YELLOW + ' The fiber track has to pass through the cerebral white matter. (Label values: ' + Colors.PURPLE + '[2, 41]' + Colors.YELLOW + ')' + Colors._CLEAR )
      c.info( Colors.PURPLE + '    2.' + Colors.YELLOW + ' The fiber track shall only touch sub-cortical structures not more than ' + Colors.PURPLE + '5 times' + Colors.YELLOW + '. (Label values: ' + Colors.PURPLE + '[10, 49, 16, 28, 60, 4, 43]' + Colors.YELLOW + ')' + Colors._CLEAR )
      c.info( Colors.PURPLE + '    3.' + Colors.YELLOW + ' The track shall not pass through the corpus callosum (Labels: ' + Colors.PURPLE + '[251, 255]' + Colors.YELLOW + ') and end in the same hemisphere (Labels: ' + Colors.PURPLE + '[1000-1035]' + Colors.YELLOW + ' for left, ' + Colors.PURPLE + '[2000-2035]' + Colors.YELLOW + ' for right).' + Colors._CLEAR )

      fyborg.fyborg( outputs['fibers_mapped_length_filtered'], outputs['fibers_mapped_length_filtered_cortex_only'], [FyFilterCortexAction( scalars.index( 'segmentation' ) )] )

      header = io.loadTrkHeaderOnly( outputs['fibers_mapped_length_filtered_cortex_only'] )
      new_count = header['n_count']

      c.info( Colors.YELLOW + '  Number of tracks after ' + Colors.PURPLE + 'cortex filtering' + Colors.YELLOW + ': ' + str( new_count ) + Colors.YELLOW + Colors._CLEAR )

      c.info( Colors.YELLOW + '  Copied filtered tracks from ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped_length_filtered_cortex_only'] )[1] + Colors.YELLOW + ' to ' + Colors.PURPLE + os.path.split( outputs['fibers_final'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
      shutil.copyfile( outputs['fibers_mapped_length_filtered_cortex_only'], outputs['fibers_final'] )

    else:

      c.info( Colors.YELLOW + '  Info: ' + Colors.PURPLE + 'Cortical _and_ sub-cortical structures ' + Colors.YELLOW + 'will be included..' + Colors._CLEAR )

      c.info( Colors.YELLOW + '  Copied filtered tracks from ' + Colors.PURPLE + os.path.split( outputs['fibers_mapped_length_filtered'] )[1] + Colors.YELLOW + ' to ' + Colors.PURPLE + os.path.split( outputs['fibers_final'] )[1] + Colors.YELLOW + '!' + Colors._CLEAR )
      shutil.copyfile( outputs['fibers_mapped_length_filtered'], outputs['fibers_final'] )
Esempio n. 20
0
File: fy.py Progetto: FNNDSC/fyborg
  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' )
Esempio n. 21
0
File: fy.py Progetto: FNNDSC/fyborg
  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 = 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()
Esempio n. 22
0
def printTrkInfo( header, fileName ):

  dimensions = header['dim']
  spacing = header['voxel_size']
  origin = header['origin']
  numberOfScalars = header['n_scalars']
  scalarNames = header['scalar_name']
  numberOfProperties = header['n_properties']
  propertyNames = header['property_name']
  voxelOrder = header['voxel_order']
  pad1 = header['pad1']
  pad2 = header['pad2']
  imageOrientation = header['image_orientation_patient']
  numberOfTracks = header['n_count']
  version = header['version']

  c.info( 'FILE: ' + fileName )

  c.info( '  TRACKVIS VERSION: ' + str( version ) )
  c.info( '  NUMBER OF TRACKS: ' + str( numberOfTracks ) )

  c.info( '  DIMENSIONS: ' + str( dimensions ) )
  c.info( '  SPACING: ' + str( spacing ) )
  c.info( '  ORIGIN: ' + str( origin ) )

  c.info( '  NUMBER OF SCALARS: ' + str( numberOfScalars ) )
  if numberOfScalars > 0:
    c.info( '    SCALARS: ' + str( scalarNames ) )

  c.info( '  NUMBER OF PROPERTIES: ' + str( numberOfProperties ) )
  if numberOfProperties > 0:
    c.info( '    PROPERTIES: ' + str( propertyNames ) )

  if version == 2:
    # only in trackvis v2
    vox2rasMatrix = header['vox_to_ras']
    c.info( '  VOX2RAS Matrix:' )
    c.info( '    ' + str( vox2rasMatrix[0] ) )
    c.info( '    ' + str( vox2rasMatrix[1] ) )
    c.info( '    ' + str( vox2rasMatrix[2] ) )
    c.info( '    ' + str( vox2rasMatrix[3] ) )

  c.info( '  VOXEL ORDER: ' + str( voxelOrder ) )
Esempio n. 23
0
    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!')
Esempio n. 24
0
    def run(self, masterFile, inputFiles, outputDirectory, spacing, dimensions,
            likefreesurfer, nii):
        '''
    Performs the equalization
    '''

        # sanity checks
        outputDirectory = os.path.normpath(outputDirectory)
        # prepare the output directory
        if os.path.exists(outputDirectory):
            c.error('The output directory already exists!')
            c.error('Aborting..')
            sys.exit(2)
        # create the output directory
        os.mkdir(outputDirectory)

        # MASTER
        masterFile = os.path.normpath(masterFile)
        # read the master
        master = io.readImage(masterFile)
        c.info('MASTER IMAGE: ' + str(masterFile))

        # INPUTS
        for i in range(len(inputFiles)):
            inputFiles[i] = os.path.normpath(inputFiles[i])
            c.info('INPUT IMAGE ' + str(i + 1) + ': ' + str(inputFiles[i]))

        # print more info
        c.info('OUTPUT DIRECTORY: ' + str(outputDirectory))

        if likefreesurfer:
            spacing = '1,1,1'
            dimensions = '256,256,256'

        if spacing != 'no':
            c.info('SET SPACINGS: ' + str(spacing))

        if dimensions != 'no':
            c.info('SET DIMENSIONS: ' + str(dimensions))

        # re-sample master to obtain an isotropic dataset
        master = self.aniso2iso(master, spacing, dimensions)
        masterFileBasename = os.path.split(masterFile)[1]
        masterFileBasenameWithoutExt = os.path.splitext(masterFileBasename)[0]

        if not nii:
            masterOutputFileName = os.path.join(outputDirectory,
                                                masterFileBasename)
        else:
            masterOutputFileName = os.path.join(
                outputDirectory, masterFileBasenameWithoutExt) + '.nii'
        io.saveImage(masterOutputFileName, master)

        # equalize all images to the master
        for i in range(len(inputFiles)):
            currentInputFile = inputFiles[i]

            c.info('Equalizing ' + str(currentInputFile) + ' to ' +
                   str(masterFile) + "...")

            # load the image
            currentImage = io.readImage(currentInputFile)
            currentImageHeader = currentImage.header
            c.info('    old spacing: ' + str(currentImageHeader.get_zooms()))
            c.info('    old dimensions: ' + str(currentImage.shape[:3]))

            # now resample
            resampledImage = resampler.resample_img2img(currentImage, master)

            # .. and save it
            currentInputFileBasename = os.path.split(currentInputFile)[1]
            currentInputFileBasenameWithoutExt = os.path.splitext(
                currentInputFileBasename)[0]
            if not nii:
                outputFileName = os.path.join(outputDirectory,
                                              currentInputFileBasename)
            else:
                outputFileName = os.path.join(
                    outputDirectory, currentInputFileBasenameWithoutExt)

            savedImage = io.saveImage(outputFileName, resampledImage)
            #c.info( '    new spacing: ' + str( savedImageHeader.get_zooms() ) )
            c.info('    new dimensions: ' + str(savedImage.shape[:3]))

        c.info('All done!')
Esempio n. 25
0
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 )