예제 #1
0
   def show_isi_stats(self, mesg='', run_len=[], tr=0, rest_file=''):
      """display ISI timing statistics

            mesg        : display the user message first
            run_len     : can be empty, length 1 or length nrows
            tr          : if > 0: show mean/stdev for stimuli within TRs
                          (so 0 <= mean < tr)
            rest_file   : if set, save all rest durations

         display these statistics:
            - total time, total stim time, total rest time

            - total time per run
            - total stim time per run
            - total rest time per run

            - pre-stim rest per run
            - post-stim response rest per run (if run_len is given)
            - total ISI rest per run

            - min/mean/max (stdev) of stim duration
            - min/mean/max (stdev) of ISI rest
      """

      if not self.ready:
         print '** M Timing: nothing to compute ISI stats from'
         return 1

      if not (self.mtype & LD.MTYPE_DUR):
         print '** warning: computing stats without duration'

      if self.nrows != len(self.data):
         print '** bad MTiming, nrows=%d, datalen=%d, failing...' % \
               (self.nrows, len(self.data))
         return 1

      # make a sorted copy
      scopy = self.copy()
      scopy.sort()

      # make a copy of format run x stim x [start,end], i.e. is 3-D
      tdata = scopy.get_start_end_timing()

      # make an updated run lengths list
      if len(run_len) == 0:
         rlens = [0 for rind in range(self.nrows)]
      elif len(run_len) == 1:
         rlens = [run_len[0] for rind in range(self.nrows)]
      elif len(run_len) == self.nrows:
         rlens = run_len
      else:     # failure
         print '** invalid len(run_len)=%d, must be one of 0,1,%d' % \
               (len(run_len), self.nrows)
         return 1

      if self.verb > 1:
         print '-- show_isi_stats, run_len = %s, tr = %s, rest_file = %s' \
               % (run_len, tr, rest_file)

      if self.verb > 3:
         print scopy.make_data_string(nplaces=1, flag_empty=0, check_simple=0,
                        mesg='scopy data')
      
      all_stim  = []    # all stimulus durations (one row per run)
      all_isi   = []    # all isi times (one row per run)
      pre_time  = []    # pre-stim, per run
      post_time = []    # pose-stim, per run
      run_time  = []    # total run time, per run
      errs      = 0     # allow a few errors before failing
      max_errs  = 10
      for rind in range(self.nrows):
         run  = tdata[rind]
         rlen = rlens[rind]

         if len(run) == 0:      # empty run
            all_stim.append([])
            all_isi.append([])
            pre_time.append(rlen)
            post_time.append(0.0)
            run_time.append(rlen)
            continue

         # if no run len specified, use end of last stimulus
         if rlen == 0.0: rlen = run[-1][1]
         elif rlen < run[-1][1]:
            print '** run %d: given length = %s, last stim ends at %s' % \
                  (rind+1, rlen, run[-1][1])
            errs += 1
            if errs > max_errs:
               print '** bailing...'
               return 1

         # pre- and post-stim times are set
         pre = run[0][0]
         post = rlen - run[-1][1]

         if pre < 0:
            print '** ISI error: first stimulus of run %d at negative time %s'%\
                  (rind+1, run[0][0])
            errs += 1
            if errs > max_errs:
               print '** bailing...'
               return 1

         # init accumulation vars
         stimes = [run[0][1] - run[0][0]]
         itimes = []

         # for each following index, update stim and isi times
         # (check for bad overlap)
         for sind in range(1, len(run)):
            if run[sind][0] < run[sind-1][1]:
               print '** ISI error: stimuli overlap at run %d, time %s' % \
                     (rind+1, run[sind][0])
               errs += 1
               if errs > max_errs:
                  print '** bailing...'
                  return 1
            stimes.append(run[sind][1]-run[sind][0])
            itimes.append(run[sind][0]-run[sind-1][1])

         # store results
         all_stim.append(stimes)
         all_isi.append(itimes)
         pre_time.append(pre)
         post_time.append(post)
         run_time.append(rlen)

      if errs > 0: return 1

      # tally the results
      rtot_stim = [] ; rtot_isi = [] ; rtot_rest = []
      stim_list = [] ; isi_list = [] ; nstim_list = []
      for rind in range(self.nrows):
         rtot_stim.append(UTIL.loc_sum(all_stim[rind]))
         rtot_rest.append(pre_time[rind] + UTIL.loc_sum(all_isi[rind]) +
                          post_time[rind])
         rtot_isi.append(UTIL.loc_sum(all_isi[rind]))
         stim_list.extend(all_stim[rind])
         isi_list.extend(all_isi[rind])
         nstim_list.append(len(all_stim[rind]))

      if mesg: mstr = '(%s) ' % mesg
      else:    mstr = ''
      print '\nISI statistics %s:\n' % mstr

      print '                        total      per run'
      print '                       ------      ------------------------------'
      print '    total time         %6.1f     %s'   % \
                 (UTIL.loc_sum(run_time), float_list_string(run_time, ndec=1))
      print '    total time: stim   %6.1f     %s'   % \
                 (UTIL.loc_sum(rtot_stim),float_list_string(rtot_stim,7,ndec=1))
      print '    total time: rest   %6.1f     %s'   % \
                 (UTIL.loc_sum(rtot_rest),float_list_string(rtot_rest,7,ndec=1))
      print ''
      print '    rest: total isi    %6.1f     %s'   % \
                 (UTIL.loc_sum(rtot_isi), float_list_string(rtot_isi,7,ndec=1))
      print '    rest: pre stim     %6.1f     %s'   % \
                 (UTIL.loc_sum(pre_time), float_list_string(pre_time,7,ndec=1))
      print '    rest: post stim    %6.1f     %s'   % \
                 (UTIL.loc_sum(post_time),float_list_string(post_time,7,ndec=1))
      print ''
      print '    num stimuli      %6d     %s'   % \
            (UTIL.loc_sum(nstim_list), float_list_string(nstim_list,7,ndec=0))
      print '\n'

      print '                         min      mean     max     stdev'
      print '                       -------  -------  -------  -------'

      print '    rest: pre-stim     %7.3f  %7.3f  %7.3f  %7.3f' % \
            (UTIL.min_mean_max_stdev(pre_time))
      print '    rest: post-stim    %7.3f  %7.3f  %7.3f  %7.3f' % \
            (UTIL.min_mean_max_stdev(post_time))
      print ''

      for ind in range(self.nrows):
         m0, m1, m2, s = UTIL.min_mean_max_stdev(all_isi[ind])
         print '    rest: run #%d ISI   %7.3f  %7.3f  %7.3f  %7.3f' % \
                    (ind, m0, m1, m2, s)

      print ''
      print '    all runs: ISI      %7.3f  %7.3f  %7.3f  %7.3f' % \
            (UTIL.min_mean_max_stdev(isi_list))
      print '    all runs: stimuli  %7.3f  %7.3f  %7.3f  %7.3f' % \
            (UTIL.min_mean_max_stdev(stim_list))
      print ''

      # and possibly print out offset info
      if tr > 0: self.show_TR_offset_stats(tr, '')

      # maybe write all rest durations
      if rest_file:
         all_rest = copy.deepcopy(all_isi)
         for run, rest in enumerate(all_rest):
             rest[:0] = [pre_time[run]]
             rest.append(post_time[run])
         UTIL.write_to_timing_file(all_rest, rest_file)

      # clean up, just to be kind
      del(all_stim); del(all_isi); del(pre_time); del(post_time); del(run_time)
      
      del(rtot_stim); del(rtot_isi); del(rtot_rest); del(stim_list)
      del(isi_list); del(nstim_list)

      del(scopy)
      del(tdata)
예제 #2
0
    def show_isi_stats(self, mesg='', run_len=[], tr=0, rest_file=''):
        """display ISI timing statistics

            mesg        : display the user message first
            run_len     : can be empty, length 1 or length nrows
            tr          : if > 0: show mean/stdev for stimuli within TRs
                          (so 0 <= mean < tr)
            rest_file   : if set, save all rest durations

         display these statistics:
            - total time, total stim time, total rest time

            - total time per run
            - total stim time per run
            - total rest time per run

            - pre-stim rest per run
            - post-stim response rest per run (if run_len is given)
            - total ISI rest per run

            - min/mean/max (stdev) of stim duration
            - min/mean/max (stdev) of ISI rest
      """

        if not self.ready:
            print '** M Timing: nothing to compute ISI stats from'
            return 1

        if not (self.mtype & LD.MTYPE_DUR):
            print '** warning: computing stats without duration'

        if self.nrows != len(self.data):
            print '** bad MTiming, nrows=%d, datalen=%d, failing...' % \
                  (self.nrows, len(self.data))
            return 1

        # make a sorted copy
        scopy = self.copy()
        scopy.sort()

        # make a copy of format run x stim x [start,end], i.e. is 3-D
        tdata = scopy.get_start_end_timing()

        # make an updated run lengths list
        if len(run_len) == 0:
            rlens = [0 for rind in range(self.nrows)]
        elif len(run_len) == 1:
            rlens = [run_len[0] for rind in range(self.nrows)]
        elif len(run_len) == self.nrows:
            rlens = run_len
        else:  # failure
            print '** invalid len(run_len)=%d, must be one of 0,1,%d' % \
                  (len(run_len), self.nrows)
            return 1

        if self.verb > 1:
            print '-- show_isi_stats, run_len = %s, tr = %s, rest_file = %s' \
                  % (run_len, tr, rest_file)

        if self.verb > 3:
            print scopy.make_data_string(nplaces=1,
                                         flag_empty=0,
                                         check_simple=0,
                                         mesg='scopy data')

        all_stim = []  # all stimulus durations (one row per run)
        all_isi = []  # all isi times (one row per run)
        pre_time = []  # pre-stim, per run
        post_time = []  # pose-stim, per run
        run_time = []  # total run time, per run
        errs = 0  # allow a few errors before failing
        max_errs = 10
        for rind in range(self.nrows):
            run = tdata[rind]
            rlen = rlens[rind]

            if len(run) == 0:  # empty run
                all_stim.append([])
                all_isi.append([])
                pre_time.append(rlen)
                post_time.append(0.0)
                run_time.append(rlen)
                continue

            # if no run len specified, use end of last stimulus
            if rlen == 0.0: rlen = run[-1][1]
            elif rlen < run[-1][1]:
                print '** run %d: given length = %s, last stim ends at %s' % \
                      (rind+1, rlen, run[-1][1])
                errs += 1
                if errs > max_errs:
                    print '** bailing...'
                    return 1

            # pre- and post-stim times are set
            pre = run[0][0]
            post = rlen - run[-1][1]

            if pre < 0:
                print '** ISI error: first stimulus of run %d at negative time %s'%\
                      (rind+1, run[0][0])
                errs += 1
                if errs > max_errs:
                    print '** bailing...'
                    return 1

            # init accumulation vars
            stimes = [run[0][1] - run[0][0]]
            itimes = []

            # for each following index, update stim and isi times
            # (check for bad overlap)
            for sind in range(1, len(run)):
                if run[sind][0] < run[sind - 1][1]:
                    print '** ISI error: stimuli overlap at run %d, time %s' % \
                          (rind+1, run[sind][0])
                    errs += 1
                    if errs > max_errs:
                        print '** bailing...'
                        return 1
                stimes.append(run[sind][1] - run[sind][0])
                itimes.append(run[sind][0] - run[sind - 1][1])

            # store results
            all_stim.append(stimes)
            all_isi.append(itimes)
            pre_time.append(pre)
            post_time.append(post)
            run_time.append(rlen)

        if errs > 0: return 1

        # tally the results
        rtot_stim = []
        rtot_isi = []
        rtot_rest = []
        stim_list = []
        isi_list = []
        nstim_list = []
        for rind in range(self.nrows):
            rtot_stim.append(UTIL.loc_sum(all_stim[rind]))
            rtot_rest.append(pre_time[rind] + UTIL.loc_sum(all_isi[rind]) +
                             post_time[rind])
            rtot_isi.append(UTIL.loc_sum(all_isi[rind]))
            stim_list.extend(all_stim[rind])
            isi_list.extend(all_isi[rind])
            nstim_list.append(len(all_stim[rind]))

        if mesg: mstr = '(%s) ' % mesg
        else: mstr = ''
        print '\nISI statistics %s:\n' % mstr

        print '                        total      per run'
        print '                       ------      ------------------------------'
        print '    total time         %6.1f     %s'   % \
                   (UTIL.loc_sum(run_time), float_list_string(run_time, ndec=1))
        print '    total time: stim   %6.1f     %s'   % \
                   (UTIL.loc_sum(rtot_stim),float_list_string(rtot_stim,7,ndec=1))
        print '    total time: rest   %6.1f     %s'   % \
                   (UTIL.loc_sum(rtot_rest),float_list_string(rtot_rest,7,ndec=1))
        print ''
        print '    rest: total isi    %6.1f     %s'   % \
                   (UTIL.loc_sum(rtot_isi), float_list_string(rtot_isi,7,ndec=1))
        print '    rest: pre stim     %6.1f     %s'   % \
                   (UTIL.loc_sum(pre_time), float_list_string(pre_time,7,ndec=1))
        print '    rest: post stim    %6.1f     %s'   % \
                   (UTIL.loc_sum(post_time),float_list_string(post_time,7,ndec=1))
        print ''
        print '    num stimuli      %6d     %s'   % \
              (UTIL.loc_sum(nstim_list), float_list_string(nstim_list,7,ndec=0))
        print '\n'

        print '                         min      mean     max     stdev'
        print '                       -------  -------  -------  -------'

        print '    rest: pre-stim     %7.3f  %7.3f  %7.3f  %7.3f' % \
              (UTIL.min_mean_max_stdev(pre_time))
        print '    rest: post-stim    %7.3f  %7.3f  %7.3f  %7.3f' % \
              (UTIL.min_mean_max_stdev(post_time))
        print ''

        for ind in range(self.nrows):
            m0, m1, m2, s = UTIL.min_mean_max_stdev(all_isi[ind])
            print '    rest: run #%d ISI   %7.3f  %7.3f  %7.3f  %7.3f' % \
                       (ind, m0, m1, m2, s)

        print ''
        print '    all runs: ISI      %7.3f  %7.3f  %7.3f  %7.3f' % \
              (UTIL.min_mean_max_stdev(isi_list))
        print '    all runs: stimuli  %7.3f  %7.3f  %7.3f  %7.3f' % \
              (UTIL.min_mean_max_stdev(stim_list))
        print ''

        # and possibly print out offset info
        if tr > 0: self.show_TR_offset_stats(tr, '')

        # maybe write all rest durations
        if rest_file:
            all_rest = copy.deepcopy(all_isi)
            for run, rest in enumerate(all_rest):
                rest[:0] = [pre_time[run]]
                rest.append(post_time[run])
            UTIL.write_to_timing_file(all_rest, rest_file)

        # clean up, just to be kind
        del (all_stim)
        del (all_isi)
        del (pre_time)
        del (post_time)
        del (run_time)

        del (rtot_stim)
        del (rtot_isi)
        del (rtot_rest)
        del (stim_list)
        del (isi_list)
        del (nstim_list)

        del (scopy)
        del (tdata)