Ejemplo n.º 1
0
def compute_TR_data(rec):
    """If writing to the serial port, this is the main function to compute
      results from rec.motion and/or rec.extras for the current TR and 
      return it as an array of floats.

      Note that motion and extras are lists of time series of length nread,
      so processing a time series is easy, but a single TR requires extracting
      the data from the end of each list.

      The possible computations is based on data_choice, specified by the user
      option -data_choice.  If you want to send data that is not listed, just
      add a condition.

   ** Please add each data_choice to the -help.  Search for motion_norm to
      find all places to edit.

      return 2 items:
        error code:     0 on success, -1 on error
        data array:     (possibly empty) array of data to send
   """

    rti = rec.RTI  # for convenience
    if not rec.data_choice: return 0, []

    # case 'motion': send all motion
    if rec.data_choice == 'motion':
        if rti.nread > 0:
            return 0, [rti.motion[ind][rti.nread - 1] for ind in range(6)]
        else:
            return -1, []

    # case 'motion_norm': send Euclidean norm of motion params
    #                     --> sqrt(sum of squared motion params)
    elif rec.data_choice == 'motion_norm':
        if rti.nread > 0:
            motion = [rti.motion[ind][rti.nread - 1] for ind in range(6)]
            return 0, [UTIL.euclidean_norm(motion)]
        else:
            return -1, []

    # case 'all_extras': send all extra data
    elif rec.data_choice == 'all_extras':
        if rti.nextra > 0:
            return 0, [rti.extras[i][rti.nread - 1] for i in range(rti.nextra)]
        else:
            return -1, []

    # case 'diff_ratio': (a-b)/(abs(a)+abs(b))
    elif rec.data_choice == 'diff_ratio':
        npairs = rti.nextra // 2
        if npairs > 0:
            vals = [rti.extras[i][rti.nread - 1] for i in range(rti.nextra)]
            # modify vals array, setting the first half to diff_ratio
            for ind in range(npairs):
                a = vals[2 * ind]
                b = vals[2 * ind + 1]
                if a == 0 and b == 0: newval = 0.0
                else: newval = (a - b) / float(abs(a) + abs(b))

                # --------------------------------------------------------------
                # VERY data dependent: convert from diff_ratio to int in {0..10}
                # assume AFNI_data6 demo                             15 Jan 2013

                # now scale [bot,inf) to {0..10}, where val>=top -> 10
                # AD6: min = -0.1717, mean = -0.1605, max = -0.1490

                bot = -0.17  # s620: bot = 0.008, scale = 43.5
                scale = 55.0  # =~ 1.0/(0.1717-0.149), rounded up
                if len(rec.dc_params) == 2:
                    bot = rec.dc_params[0]
                    scale = rec.dc_params[1]

                val = newval - bot
                if val < 0.0: val = 0.0
                ival = int(10 * val * scale)
                if ival > 10: ival = 10

                vals[ind] = ival

                if rti.verb > 1:
                    if rti.verb > 2: pstr = ', (params = %s)' % rec.dc_params
                    else: pstr = ''
                    print '++ diff_ratio: ival = %d (from %s)%s' % (
                        ival, newval, pstr)

                return 0, vals[0:npairs]  # return the partial list

        else:
            if rti.verb > 0 and rti.nread < 2:
                print '** no pairs to compute diff_ratio from...'
            return 0, []

    # failure!
    else:
        print "** invalid data_choice '%s', shutting down ..." % rec.data_choice
        return -1, []
Ejemplo n.º 2
0
def compute_TR_data(rec):
   """If writing to the serial port, this is the main function to compute
      results from rec.motion and/or rec.extras for the current TR and 
      return it as an array of floats.

      Note that motion and extras are lists of time series of length nread,
      so processing a time series is easy, but a single TR requires extracting
      the data from the end of each list.

      The possible computations is based on data_choice, specified by the user
      option -data_choice.  If you want to send data that is not listed, just
      add a condition.

   ** Please add each data_choice to the -help.  Search for motion_norm to
      find all places to edit.

      return 2 items:
        error code:     0 on success, -1 on error
        data array:     (possibly empty) array of data to send
   """

   rti = rec.RTI       # for convenience
   if not rec.data_choice: return 0, []

   # case 'motion': send all motion
   if rec.data_choice == 'motion':
      if rti.nread > 0:
         return 0, [rti.motion[ind][rti.nread-1] for ind in range(6)]
      else: return -1, []

   # case 'motion_norm': send Euclidean norm of motion params
   #                     --> sqrt(sum of squared motion params)
   elif rec.data_choice == 'motion_norm':
      if rti.nread > 0:
         motion = [rti.motion[ind][rti.nread-1] for ind in range(6)]
         return 0, [UTIL.euclidean_norm(motion)]
      else: return -1, []

   # case 'all_extras': send all extra data
   elif rec.data_choice == 'all_extras':
      if rti.nextra > 0:
         return 0, [rti.extras[i][rti.nread-1] for i in range(rti.nextra)]
      else: return -1, []

   # case 'diff_ratio': (a-b)/(abs(a)+abs(b))
   elif rec.data_choice == 'diff_ratio':
      npairs = rti.nextra//2
      if npairs > 0:
         vals = [rti.extras[i][rti.nread-1] for i in range(rti.nextra)]
         # modify vals array, setting the first half to diff_ratio
         for ind in range(npairs):
            a = vals[2*ind]
            b = vals[2*ind+1]
            if a == 0 and b == 0: newval = 0.0
            else: newval = (a-b)/float(abs(a)+abs(b))

            # --------------------------------------------------------------
            # VERY data dependent: convert from diff_ratio to int in {0..10}
            # assume AFNI_data6 demo                             15 Jan 2013

            # now scale [bot,inf) to {0..10}, where val>=top -> 10
            # AD6: min = -0.1717, mean = -0.1605, max = -0.1490

            bot = -0.17         # s620: bot = 0.008, scale = 43.5
            scale = 55.0        # =~ 1.0/(0.1717-0.149), rounded up
            if len(rec.dc_params) == 2:
               bot = rec.dc_params[0]
               scale = rec.dc_params[1]

            val = newval-bot
            if val < 0.0: val = 0.0
            ival = int(10*val*scale)
            if ival > 10: ival = 10

            vals[ind] = ival

            if rti.verb > 1:
               if rti.verb > 2: pstr = ', (params = %s)' % rec.dc_params
               else:            pstr = ''
               print '++ diff_ratio: ival = %d (from %s)%s'%(ival,newval,pstr)

            return 0, vals[0:npairs]    # return the partial list

      else:
         if rti.verb > 0 and rti.nread < 2:
            print '** no pairs to compute diff_ratio from...'
         return 0, []

   # failure!
   else:
      print "** invalid data_choice '%s', shutting down ..." % rec.data_choice
      return -1, []