示例#1
0
def StimulusTiming(filename='.',
                   ind=None,
                   channels=0,
                   trigger='StimulusCode > 0',
                   msec=300,
                   offset_msec=0,
                   rectify=False,
                   threshold=0.1,
                   use_eo=False,
                   save=None,
                   **kwargs):
    """
In <filename> and <ind>, give it
  - a directory and ind=None:  for all .dat files in the directory, in session/run order
  - a directory and ind=an index or list of indices: for selected .dat files in the directory
  - a dat-file name and ind=anything:  for that particular file
  - a list of filenames and ind=anything: for certain explicitly-specified files

<channels>  may be a 0-based index, list of indices, list of channel names, or space- or comma-
			delimited string of channel names
<rectify>   subtracts the median and takes the abs before doing anything else
<threshold> is on the normalized scale of min=0, max=1 within the resulting image
<use_eo>    uses the EventOffset state to correct timings
	"""###
    if hasattr(filename, 'filename'): filename = filename.filename

    if ind == None:
        ind = -1
        if os.path.isdir(filename): filename = ListDatFiles(filename)

    if not isinstance(filename, (tuple, list)): filename = [filename]
    if not isinstance(ind, (tuple, list)): ind = [ind]
    n = max(len(filename), len(ind))
    if len(filename) == 1: filename = list(filename) * n
    if len(ind) == 1: ind = list(ind) * n

    if isinstance(channels, str): channels = channels.replace(',', ' ').split()
    if not isinstance(channels, (tuple, list)): channels = [channels]
    out = [
        SigTools.sstruct(
            files=[],
            events=[],
            t=None,
            channel=ch,
            img=[],
            edges=[],
            threshold=None,
            EventOffsets=[],
            UseEventOffsets=False,
        ) for ch in channels
    ]
    if len(filename) == 0: raise ValueError("no data files specified")
    for f, i in zip(filename, ind):
        b = bcistream(filename=f, ind=i)
        nsamp = b.msec2samples(msec)
        nsamp_offset = b.msec2samples(offset_msec)
        sig, st = b.decode('all')
        statenames = list(zip(*sorted([(-len(x), x) for x in st])))[1]
        criterion = trigger
        for x in statenames:
            criterion = criterion.replace(x, "st['%s']" % x)
        criterion = numpy.asarray(eval(criterion)).flatten()
        startind = SigTools.edges(criterion)
        print("%d events found in %s" % (len(startind), b.filename))

        for s in out:
            s.files.append(b.filename)
            s.events.append(len(startind))
            ch = s.channel
            if isinstance(ch, str):
                chn = [x.lower() for x in b.params['ChannelNames']]
                if ch.lower() in chn: ch = chn.index(ch.lower())
                else:
                    raise ValueError("could not find channel %s in %s" %
                                     (ch, b.filename))
            if len(b.params['ChannelNames']) == len(sig):
                s.channel = b.params['ChannelNames'][ch]

            xx = numpy.asarray(sig)[ch]
            if rectify: xx = numpy.abs(xx - numpy.median(xx))
            xx -= xx.min()
            if xx.max(): xx /= xx.max()
            s.threshold = threshold
            for ind in startind:
                if 'EventOffset' in st:
                    eo = st['EventOffset'].flat[ind]
                    if use_eo:
                        ind += eo - 2**(b.statedefs['EventOffset']['length'] -
                                        1)
                        s.UseEventOffsets = True
                else:
                    eo = 0
                s.EventOffsets.append(eo)
                x = xx[ind + nsamp_offset:ind + nsamp_offset + nsamp].tolist()
                x += [0.0] * (nsamp - len(x))
                s.img.append(x)

    for s in out:
        s.img = numpy.asarray(s.img)
        s.edges = [
            min(list(x.nonzero()[0]) + [numpy.nan])
            for x in (s.img > s.threshold)
        ]
        s.edges = b.samples2msec(numpy.asarray(s.edges + nsamp_offset))
        s.t = b.samples2msec(numpy.arange(nsamp_offset, nsamp_offset + nsamp))

    import pylab
    pylab.clf()
    ax = None
    for i, s in enumerate(out):
        ax = pylab.subplot(1, len(out), i + 1, sharex=ax, sharey=ax)
        y = y = list(range(1, len(s.img) + 1))
        SigTools.imagesc(s.img, x=s.t, y=y, aspect='auto', **kwargs)
        xl, yl = pylab.xlim(), pylab.ylim()
        pylab.plot(s.edges, y, 'w*', markersize=10)
        for j, x in enumerate(s.edges.flat):
            if not numpy.isnan(x):
                pylab.text(x,
                           y[j],
                           str(y[j]) + '---',
                           ha='right',
                           va='center',
                           color='#00FF00',
                           clip_on=True)
        pylab.xlim(xl)
        pylab.ylim(yl)
        pylab.grid('on')
        #pylab.ylim([len(s.img)+0.5,0.5]) # this corrupts the image!!
    pylab.draw()
    if save:
        pylab.gcf().savefig(save, orientation='portrait')
    return out