예제 #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 proc_mats(uopts):
    offset = 0.0  # offset for output times

    if uopts == None: return

    opt = uopts.find_opt('-verb')
    if opt:
        try:
            verb = int(opt.parlist[0])
        except:
            print("** error: verb must be int, have '%s'" % opt.parlist[0])
            return
    else:
        verb = 0

    opt = uopts.find_opt('-files')
    files = opt.parlist

    consec_ok = (uopts.find_opt('-no_consec') == None)

    # set run_trs nruns from either -run_trs or -nruns and -nt
    opt = uopts.find_opt('-run_trs')
    if opt:
        val, err = uopts.get_type_list(int, '', opt=opt)
        if err: return 1
        run_trs = val
        nruns = len(run_trs)
        if uopts.find_opt('-nruns') or uopts.find_opt('-nt'):
            print('** please use either -run_trs or -nt/-nruns')
            return 1
    else:
        if not uopts.find_opt('-nruns') or not uopts.find_opt('-nt'):
            print('** please use either -run_trs or both -nt and -nruns')
            return 1
        opt = uopts.find_opt('-nruns')
        nruns = int(opt.parlist[0])

        opt = uopts.find_opt('-nt')
        try:
            nt = int(opt.parlist[0])
        except:
            print("** error: -nt must be int, have '%s'" % opt.parlist[0])
            return
        run_trs = [nt] * nruns

    # note the total number of TRs, regardless
    ntotal = afni_util.loc_sum(run_trs)

    opt = uopts.find_opt('-offset')
    if opt:
        try:
            offset = float(opt.parlist[0])
        except:
            print("** error: offset must be float, have '%s'" % opt.parlist[0])
            return

    opt = uopts.find_opt('-prefix')
    prefix = opt.parlist[0]

    opt = uopts.find_opt('-tr')
    try:
        tr = float(opt.parlist[0])
    except:
        print("** error: TR must be float, have '%s'" % opt.parlist[0])
        return

    opt = uopts.find_opt('-labels')
    if opt: labels = opt.parlist
    else: labels = []
    nlab = len(labels)

    # print some info
    if verb:        print("-- run_trs = %s, TR = %s, %d labels" \
              % (run_trs, str(tr), nlab))

    # new option, -amplitudes (columns of amplitudes to Marry, not just 1s)
    use_amp = 0
    opt = uopts.find_opt('-amplitudes')
    if opt:
        use_amp = 1
        if verb: print('-- using amplitudes to Marry with times...')

    newfile_index = 1  # index over output files
    for fname in files:
        tmat = TD.read_1D_file(fname, verb=verb)
        if not tmat:
            print("read_1D_file failed for file: %s" % fname)
            return
        mat = afni_util.transpose(tmat)
        del (tmat)

        if len(mat[0]) < ntotal:
            print('** error: file %s has only %d entries (%d required)' % \
                  (fname, len(mat[0]), ntotal))
            return
        elif len(mat[0]) > ntotal:
            print('** warning: file %s has %d entries (expected only %d)' % \
                  (fname, len(mat[0]), ntotal))

        for row in mat:

            # maybe add a label to the file name
            if newfile_index <= nlab: label = ".%s" % labels[newfile_index - 1]
            elif nlab == 0: label = ""
            else:
                print("** %d labels given, but we are on column %d..." % \
                      (nlab, newfile_index))
                label = ".label%d" % (newfile_index)

            newp = "%s.%02d%s" % (prefix, newfile_index, label)
            newfile = afni_util.change_path_basename(fname, newp + ".1D")
            if newfile == None: return
            if prefix == '-' or prefix == 'stdout': fp = sys.stdout
            elif prefix == 'stderr': fp = sys.stderr
            else: fp = open(newfile, 'w')

            blocked_consec = 0  # note whether we block consecutive events
            runend = -1
            for run in range(nruns):
                runstart = runend + 1
                runend = runstart + run_trs[run] - 1
                # old: rindex = run * nt   # point to start of run
                rindex = runstart

                # if empty run, use placeholders
                if not stim_in_run(row[runstart:runend + 1], use_amp):
                    if run == 0: fp.write('* *\n')  # first run gets 2
                    else: fp.write('*\n')
                    continue
                # print '=== have stim in run, row = %s' % row[rindex:rindex+nt]
                time = 0  # in this run
                nstim = 0  # be sure we have more than 1 somewhere
                first = 1  # first occurance if no consec
                for lcol in range(run_trs[run]):
                    if row[rindex + lcol]:
                        # note whether anything has been blocked
                        if not first and not consec_ok:
                            if verb > 2:
                                print('-- blocked consec: file %s, run %d, ind %d'\
                                      % (newp, run, lcol))
                            blocked_consec = 1

                        # if consec is bad, only write on first occurance
                        if first or consec_ok:
                            nstim += 1
                            tstr = '%s' % str(time + offset)

                            # if -amplitudes write as time*amplitude
                            if use_amp: astr = '*%s' % str(row[rindex + lcol])
                            else: astr = ''

                            fp.write('%s%s ' % (tstr, astr))

                        first = 0  # not first occurance
                    else:
                        first = 1

                    time += tr
                if run == 0 and nstim == 1:
                    fp.write('*')  # if first time has 1 stim, add '*'
                fp.write('\n')

            if fp != sys.stdout and fp != sys.stderr: fp.close()
            newfile_index += 1

            if verb and blocked_consec:
                print('-- blocked consecutive events file %s, output %s' \
                      % (fname, newp))
예제 #3
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)
예제 #4
0
def proc_mats(uopts):
    offset = 0.0  # offset for output times

    if uopts == None: return

    opt = uopts.find_opt('-verb')
    if opt:
        try:
            verb = int(opt.parlist[0])
        except:
            print "** error: verb must be int, have '%s'" % opt.parlist[0]
            return
    else:
        verb = 0

    opt = uopts.find_opt('-files')
    files = opt.parlist

    # set run_trs nruns from either -run_trs or -nruns and -nt
    opt = uopts.find_opt('-run_trs')
    if opt:
        val, err = uopts.get_type_list(int, '', opt=opt)
        if err: return 1
        run_trs = val
        nruns = len(run_trs)
        if uopts.find_opt('-nruns') or uopts.find_opt('-nt'):
            print '** please use either -run_trs or -nt/-nruns'
            return 1
    else:
        if not uopts.find_opt('-nruns') and not uopts.find_opt('-nt'):
            print '** please use either -run_trs or -nt/-nruns (missing one)'
            return 1
        opt = uopts.find_opt('-nruns')
        nruns = int(opt.parlist[0])

        opt = uopts.find_opt('-nt')
        try:
            nt = int(opt.parlist[0])
        except:
            print "** error: -nt must be int, have '%s'" % opt.parlist[0]
            return
        run_trs = [nt] * nruns

    # not the total number of TRs, regardless
    ntotal = afni_util.loc_sum(run_trs)

    opt = uopts.find_opt('-offset')
    if opt:
        try:
            offset = float(opt.parlist[0])
        except:
            print "** error: offset must be float, have '%s'" % opt.parlist[0]
            return

    opt = uopts.find_opt('-prefix')
    prefix = opt.parlist[0]

    opt = uopts.find_opt('-tr')
    try:
        tr = float(opt.parlist[0])
    except:
        print "** error: TR must be float, have '%s'" % opt.parlist[0]
        return

    opt = uopts.find_opt('-labels')
    if opt: labels = opt.parlist
    else: labels = []
    nlab = len(labels)

    # print some info
    if verb:        print "-- run_trs = %s, TR = %s, %d labels" \
              % (run_trs, str(tr), nlab)

    # new option, -amplitudes (columns of amplitudes to Marry, not just 1s)
    use_amp = 0
    opt = uopts.find_opt('-amplitudes')
    if opt:
        use_amp = 1
        if verb: print '-- using amplitudes to Marry with times...'

    newfile_index = 1  # index over output files
    for file in files:
        tmat = TD.read_1D_file(file, verb=verb)
        if not tmat:
            print "read_1D_file failed for file: %s" % file
            return
        mat = afni_util.transpose(tmat)
        del (tmat)

        if len(mat[0]) < ntotal:
            print '** error: file %s has only %d entries (%d required)' % \
                  (file, len(mat[0]), ntotal)
            return
        elif len(mat[0]) > ntotal:
            print '** warning: file %s has %d entries (expected only %d)' % \
                  (file, len(mat[0]), ntotal)

        for row in mat:

            # maybe add a label to the file name
            if newfile_index <= nlab: label = ".%s" % labels[newfile_index - 1]
            elif nlab == 0: label = ""
            else:
                print "** %d labels given, but we are on column %d..." % \
                      (nlab, newfile_index)
                label = ".label%d" % (newfile_index)

            newp = "%s.%02d%s" % (prefix, newfile_index, label)
            newfile = afni_util.change_path_basename(file, newp, ".1D")
            if newfile == None: return
            fp = open(newfile, 'w')

            runend = -1
            for run in range(nruns):
                runstart = runend + 1
                runend = runstart + run_trs[run] - 1
                # old: rindex = run * nt   # point to start of run
                rindex = runstart

                # if empty run, use placeholders
                if not stim_in_run(row[runstart:runend + 1], use_amp):
                    if run == 0: fp.write('* *\n')  # first run gets 2
                    else: fp.write('*\n')
                    continue
                # print '=== have stim in run, row = %s' % row[rindex:rindex+nt]
                time = 0  # in this run
                nstim = 0  # be sure we have more than 1 somewhere
                for lcol in range(run_trs[run]):
                    if row[rindex + lcol]:
                        nstim += 1
                        # if -amplitudes write as time:amplitude
                        if use_amp:
                            fp.write('%s*%s ' % \
                                     (str(time+offset),str(row[rindex+lcol])))
                        else:
                            fp.write('%s ' % str(time + offset))
                    time += tr
                if run == 0 and nstim == 1:
                    fp.write('*')  # if first time has 1 stim, add '*'
                fp.write('\n')

            fp.close()
            newfile_index += 1
def proc_mats(uopts):
    offset = 0.0        # offset for output times

    if uopts == None: return

    opt = uopts.find_opt('-verb')
    if opt:
        try: verb = int(opt.parlist[0])
        except:
            print "** error: verb must be int, have '%s'" % opt.parlist[0]
            return
    else: verb = 0

    opt    = uopts.find_opt('-files')
    files  = opt.parlist

    consec_ok = (uopts.find_opt('-no_consec') == None)

    # set run_trs nruns from either -run_trs or -nruns and -nt
    opt    = uopts.find_opt('-run_trs')
    if opt:
       val, err = uopts.get_type_list(int, '', opt=opt)
       if err: return 1
       run_trs = val
       nruns = len(run_trs)
       if uopts.find_opt('-nruns') or uopts.find_opt('-nt'):
          print '** please use either -run_trs or -nt/-nruns'
          return 1
    else:
       if not uopts.find_opt('-nruns') or not uopts.find_opt('-nt'):
          print '** please use either -run_trs or both -nt and -nruns'
          return 1
       opt    = uopts.find_opt('-nruns')
       nruns = int(opt.parlist[0])

       opt    = uopts.find_opt('-nt')
       try: nt = int(opt.parlist[0])
       except:
           print "** error: -nt must be int, have '%s'" % opt.parlist[0]
           return
       run_trs = [nt]*nruns

    # note the total number of TRs, regardless
    ntotal = afni_util.loc_sum(run_trs)

    opt    = uopts.find_opt('-offset')
    if opt:
        try: offset = float(opt.parlist[0])
        except:
            print "** error: offset must be float, have '%s'" % opt.parlist[0]
            return

    opt    = uopts.find_opt('-prefix')
    prefix = opt.parlist[0]

    opt    = uopts.find_opt('-tr')
    try: tr = float(opt.parlist[0])
    except:
        print "** error: TR must be float, have '%s'" % opt.parlist[0]
        return

    opt = uopts.find_opt('-labels')
    if opt: labels = opt.parlist
    else:   labels = []
    nlab = len(labels)

    # print some info
    if verb: print "-- run_trs = %s, TR = %s, %d labels" \
                   % (run_trs, str(tr), nlab)

    # new option, -amplitudes (columns of amplitudes to Marry, not just 1s)
    use_amp = 0
    opt = uopts.find_opt('-amplitudes')
    if opt:
        use_amp = 1
        if verb: print '-- using amplitudes to Marry with times...'
    
    newfile_index = 1   # index over output files
    for fname in files:
        tmat = TD.read_1D_file(fname, verb=verb)
        if not tmat:
            print "read_1D_file failed for file: %s" % fname
            return
        mat = afni_util.transpose(tmat)
        del(tmat)

        if len(mat[0]) < ntotal:
            print '** error: file %s has only %d entries (%d required)' % \
                  (fname, len(mat[0]), ntotal)
            return
        elif len(mat[0]) > ntotal:
            print '** warning: file %s has %d entries (expected only %d)' % \
                  (fname, len(mat[0]), ntotal)

        for row in mat:

            # maybe add a label to the file name
            if newfile_index <= nlab: label = ".%s" % labels[newfile_index-1]
            elif nlab == 0:           label = ""
            else:
                print "** %d labels given, but we are on column %d..." % \
                      (nlab, newfile_index)
                label = ".label%d" % (newfile_index)

            newp = "%s.%02d%s" % (prefix,newfile_index,label)
            newfile = afni_util.change_path_basename(fname, newp, ".1D")
            if newfile == None: return
            if   prefix == '-' or prefix == 'stdout': fp = sys.stdout
            elif prefix == 'stderr':                  fp = sys.stderr
            else:                                     fp = open(newfile, 'w')

            blocked_consec = 0  # note whether we block consecutive events
            runend = -1
            for run in range(nruns):
                runstart = runend + 1
                runend = runstart + run_trs[run] - 1
                # old: rindex = run * nt   # point to start of run
                rindex = runstart

                # if empty run, use placeholders
                if not stim_in_run(row[runstart:runend+1], use_amp):
                    if run == 0: fp.write('* *\n')  # first run gets 2
                    else:        fp.write('*\n')
                    continue
                # print '=== have stim in run, row = %s' % row[rindex:rindex+nt]
                time = 0        # in this run
                nstim = 0       # be sure we have more than 1 somewhere
                first = 1       # first occurance if no consec
                for lcol in range(run_trs[run]):
                    if row[rindex+lcol]:
                       # note whether anything has been blocked
                       if not first and not consec_ok:
                          if verb > 2:
                             print '-- blocked consec: file %s, run %d, ind %d'\
                                   % (newp, run, lcol)
                          blocked_consec = 1

                       # if consec is bad, only write on first occurance
                       if first or consec_ok:
                         nstim += 1
                         tstr = '%s' % str(time+offset)

                         # if -amplitudes write as time*amplitude
                         if use_amp: astr = '*%s' % str(row[rindex+lcol])
                         else:       astr = ''

                         fp.write('%s%s ' % (tstr, astr))

                       first = 0 # not first occurance
                    else: first = 1

                    time += tr
                if run == 0 and nstim == 1:
                    fp.write('*')   # if first time has 1 stim, add '*'
                fp.write('\n')

            if fp != sys.stdout and fp != sys.stderr: fp.close()
            newfile_index += 1

            if verb and blocked_consec:
               print '-- blocked consecutive events file %s, output %s' \
                     % (fname, newp)