示例#1
0
    def __init__(self):
        self.prefix = "data/"
        self.images_prefix = 'speller_images/'
        self.samples = None
        self.hasPCA = False
        self.isi = 120 # speller stim interval in ms
        self.stimnum = 4
        self.trials = 20
        self.do_channel_mask = False
        self.mode = None

        self.loadData()
        self.images = int(((self.stimnum/2) ** 2)/2)

        self.lslrec = Lslrecorder()
        if(self.lslrec.findStream() == -1):
            return
        if self.do_channel_mask is True:
            self.channels = 9
        else:
            self.channels = self.lslrec.channelCount
        self.lslrec.startRec()
        app = QApplication(sys.argv)
        self.presentation = StimulusPresentation(quit_with_escape=True)

        # init speller-mode with image path and inter-stimulus-interval,
        self.presentation.initialize(path=self.images_prefix, inter_stimulus_interval=120,
                                     n_images=self.images, mode=self.mode)

        # show window
        self.presentation.show()

        # detect targets
        self.detectTargets()
        sys.exit(app.exec_())
示例#2
0
    def __init__(self):
        ###########################################################
        # USER CONFIGURATION:
        # SPECIFY PARAMETERS FOR THE EXPERIMENT
        ###########################################################
        self.data_prefix = 'data/'  # Full path to directory where to save the data
        self.images_prefix = 'speller_images/'  # Full path to directory where the stimulus images are located
        self.trials = 5
        self.subtrials = 10
        self.stimnum = 8
        # Possible modes:
        # PresentationMode.SPELLER_MODE (0): Stimuli arranged as square matrix. Rows and columns are highlighted.
        # PresentationMode.SEQUENCE_MODE (1): Stimuli are arranged side by side in middle of screen, each highlighted individually.
        # PresentationMode.CIRCULAR_SEQUENCE_MODE (2): Stimuli are arranged in a circle and highlighted individually.
        # Hint: Data processing for mode 1 and 2 is identical.
        self.mode = PresentationMode.SPELLER_MODE

        ###########################################################
        # DO NOT CHANGE CODE BELOW UNLESS YOU REALLY KNOW WHAT
        # YOU ARE DOING !!!
        ###########################################################

        self.images = self.stimnum

        # important lists
        self.onsets = []
        self.flashseq = []
        self.targets = []
        while len(self.targets) < self.trials:
            self.targets += list(range(0, self.stimnum))
        shuffle(self.targets)
        self.targets = self.targets[0:self.trials]

        # create lsl recorder and start rec
        # ording data + timestamps
        self.lslrec = Lslrecorder()
        print("Created lsl recorder")
        if self.lslrec.findStream() == -1:
            return
        self.lslrec.startRec()

        # start qt app and play experiment
        app = QApplication(sys.argv)
        self.presentation = StimulusPresentation()
        self.doPresentation()

        # shut everything down and save gathered data to data directory
        time.sleep(30)
        self.lslrec.stopRec()
        self.saveData()
        sys.exit(app.exec_())
示例#3
0
class P3_classify():
    def __init__(self):
        self.prefix = "data/"
        self.images_prefix = 'speller_images/'
        self.samples = None
        self.hasPCA = False
        self.isi = 120 # speller stim interval in ms
        self.stimnum = 4
        self.trials = 20
        self.do_channel_mask = False
        self.mode = None

        self.loadData()
        self.images = int(((self.stimnum/2) ** 2)/2)

        self.lslrec = Lslrecorder()
        if(self.lslrec.findStream() == -1):
            return
        if self.do_channel_mask is True:
            self.channels = 9
        else:
            self.channels = self.lslrec.channelCount
        self.lslrec.startRec()
        app = QApplication(sys.argv)
        self.presentation = StimulusPresentation(quit_with_escape=True)

        # init speller-mode with image path and inter-stimulus-interval,
        self.presentation.initialize(path=self.images_prefix, inter_stimulus_interval=120,
                                     n_images=self.images, mode=self.mode)

        # show window
        self.presentation.show()

        # detect targets
        self.detectTargets()
        sys.exit(app.exec_())

    def detectTargets(self):
        other = -1 
        first_target = -1
        found = 0
        for i in range(self.trials):
            s = 1
            target = -1
            if self.mode == PresentationMode.SPELLER_MODE:
                TP = np.zeros((int(self.stimnum/2),int(self.stimnum/2)))
            else:
                TP = np.zeros((self.stimnum))
                print(colored("TP has length: %s " % len(TP), 'green'))

            #Show only blank matrix to allow user to choose symbol
            self.presentation.show_target(-2, '', show_matrix=True)

                # % Subtrial loop. Executed until a target is detected or max. number
                # % of subtrials is reached.
            while target == -1 :

                flash =self.presentation.execute_sub_trial()
                on = np.array([int(i[1]) for i in flash])
                fseq = np.array([int(i[0]) for i in flash])

                # wait for all data to be collected
                time.sleep(1)

                (target,TP) = self.processSubtrial(on ,fseq, s, TP)
                print(target)
                print(TP)
                s=s+1

            if self.mode == PresentationMode.SPELLER_MODE:
                #    % Expand row/col to linear index [0...(stimnum/2)^2-1]
                target = (target[1])*(self.stimnum/2)+target[0]
            target = int(target)
            print(colored("The current target has index %s." % target, 'magenta'))
            (index, turned) = self.presentation.fields[target]
            if not turned:
                 self.presentation.fields[target] = (index, True)
                 self.presentation.show_target(target, 'Detected Target')
                 if other >= 0:
                     if other != index:
                         self.presentation.fields[target] = (index, False)
                         (other_index, turned) = self.presentation.fields[other]
                         self.presentation.fields[first_target] = (other_index, False)
                         other = -1            
                     else:
                         other = -1
                         found += 1
                         if found == self.images: return
                 else:
                     other = index
                     first_target = target


    def processSubtrial(self, on, fseq, s, TP):
        self.dataset = np.zeros((self.stimnum,self.samples,self.channels))
        for (stim, onset) in zip(list(range(self.stimnum)),on):
            ind = (np.abs(self.lslrec.timeStamps - onset)).argmin()
            # print("closest timestamp: ",int(self.lslrec.timeStamps[ind]))
            thresh = (1000/self.lslrec.srate)*2
            diff = abs(int(self.lslrec.timeStamps[ind]) - onset)
            #print(diff, thresh)
            if diff > thresh:
                print('difference between timestamps is %d ms. Something is wrong' % diff)
                return
            self.dataset[stim] = self.getDataAtIndex(ind)
        #print(self.dataset.shape)

        if (not self.hasPCA):
            self.dataset = downsample(self.dataset, 10, avg="pick")
            #print("downsampled dataset:")
            #print(self.dataset.shape)

        self.dataset = self.dataset.transpose((0, 2, 1))
        self.dataset = self.dataset.reshape(self.stimnum, -1)

        # apply pca
        if self.hasPCA:
            self.dataset = np.matmul(self.dataset,self.pcamat)

        # apply classification
        ys = np.matmul(self.dataset,self.fda_w) + self.fda_b
        return self.subtrialDynamic(ys, fseq, TP, s)

    def subtrialDynamic(self, ys, flashseq, TPprev, subtrcount, maxRep = 10):

        # % function [target,TPcurr] = class_subtrial_dynamic(ys,flashseq,TPprev,sbtrcount,Mthresh,isSpeller,maxrep)
        # %
        # % THIS IS EXECUTED ONCE PER SUBTRIAL !
        # %
        # % INPUT
        # %   flashseq    [stimnum x 1]
        # %   ys          [stimnum x 1]
        # %   TPprev      Current score matrix
        # %   sbtrcount   Current repetion
        # %   Mthresh     Matrix brightness threshold
        # %   maxrep      Maximal number of subtrials
        # %
        # % OUTPUT
        # %   target      index of decoded stimulus

        dummy = np.array(list(zip(flashseq, ys))).transpose()
        dummy = dummy[:, np.argsort(dummy[0])]

        if self.mode == PresentationMode.SPELLER_MODE:
            rc = int(len(flashseq)/2)
            TPcurr = TPprev + np.tile(dummy[1][0:rc],(rc,1))+np.tile(dummy[1][rc:],(rc,1)).transpose()

            M = sum(Scale(TPcurr.flatten(),0,1))
            #print("sum over scaled TP")
            #print(M)

            max_idx = np.argmax(TPcurr)
            max_col = int(np.floor(max_idx / rc))
            max_row = int(max_idx-(max_col*rc))

            target = [max_col,max_row]
            #print(TPcurr[max_col,max_row])



        # TODO NOT speller case
        else:
            TPcurr = TPprev + dummy[1, :]
            M = sum(Scale(TPcurr.flatten(), 0, 1))
            print(colored("M = %s " % M, 'magenta'))
            print(colored("M_thr is %s " % self.M_thr, 'red'))
            print(colored("TPcurr has shape: %s: " % len(TPcurr), 'magenta'))
            print(TPcurr)
            target = np.argmax(TPcurr)
        # else

        #Check if we haven't met criteria yet and need to issue another subtrial
        #print("TPcurr")
        #print(TPcurr)
        if(M > self.M_thr and subtrcount<maxRep):
            target = -1
        print("M is currently %s" % M)
        return target, TPcurr

    def getDataAtIndex(self,i):
        returnData = self.lslrec.data[i:i+self.samples][:]
        if self.do_channel_mask is True:
            mask = [2, 3, 4, 5, 6, 7, 14, 15, 16]
            returnData = filter.filter_data(returnData[:, mask].T, self.srate, l_freq=0.1, h_freq=None, method='iir', n_jobs=6)
            returnData = returnData.T
        return returnData

    def loadData(self):
        if self.hasPCA:
            self.pcamat = np.load(self.prefix + "pcamat.npy")
        self.fda_w = np.load(self.prefix + "fda_w.npy")
        self.fda_b = float(np.load(self.prefix + "fda_b.npy"))
        self.Tp_thr = float(np.load(self.prefix + "Tp_thr.npy"))
        self.M_thr = float(np.load(self.prefix + "M_thr.npy"))
        print("Threshold for dyn lim is %s" % self.M_thr)
        self.srate = int(np.load(self.prefix + "srate.npy"))
        self.samples = int(0.8 * self.srate)
        self.mode = np.load(self.prefix + "presentation_mode.npy")
        print("loaded data from " + self.prefix)
示例#4
0
class P3_train():
    def __init__(self):
        ###########################################################
        # USER CONFIGURATION:
        # SPECIFY PARAMETERS FOR THE EXPERIMENT
        ###########################################################
        self.data_prefix = 'data/'  # Full path to directory where to save the data
        self.images_prefix = 'speller_images/'  # Full path to directory where the stimulus images are located
        self.trials = 5
        self.subtrials = 10
        self.stimnum = 8
        # Possible modes:
        # PresentationMode.SPELLER_MODE (0): Stimuli arranged as square matrix. Rows and columns are highlighted.
        # PresentationMode.SEQUENCE_MODE (1): Stimuli are arranged side by side in middle of screen, each highlighted individually.
        # PresentationMode.CIRCULAR_SEQUENCE_MODE (2): Stimuli are arranged in a circle and highlighted individually.
        # Hint: Data processing for mode 1 and 2 is identical.
        self.mode = PresentationMode.SPELLER_MODE

        ###########################################################
        # DO NOT CHANGE CODE BELOW UNLESS YOU REALLY KNOW WHAT
        # YOU ARE DOING !!!
        ###########################################################

        self.images = self.stimnum

        # important lists
        self.onsets = []
        self.flashseq = []
        self.targets = []
        while len(self.targets) < self.trials:
            self.targets += list(range(0, self.stimnum))
        shuffle(self.targets)
        self.targets = self.targets[0:self.trials]

        # create lsl recorder and start rec
        # ording data + timestamps
        self.lslrec = Lslrecorder()
        print("Created lsl recorder")
        if self.lslrec.findStream() == -1:
            return
        self.lslrec.startRec()

        # start qt app and play experiment
        app = QApplication(sys.argv)
        self.presentation = StimulusPresentation()
        self.doPresentation()

        # shut everything down and save gathered data to data directory
        time.sleep(30)
        self.lslrec.stopRec()
        self.saveData()
        sys.exit(app.exec_())

    def doPresentation(self):
        # init speller-mode with image path and inter-stimulus-interval,
        # number of stimuli to load, and presentation mode
        self.presentation.initialize(path=self.images_prefix,
                                     inter_stimulus_interval=120,
                                     n_images=self.images,
                                     mode=self.mode)
        self.presentation.show()

        for trial in range(0, self.trials):
            print("displaying trial " + str(trial) + " " +
                  str(self.targets[trial]))
            self.presentation.show_target(self.targets[trial],
                                          'Focus on this Target', True)
            for subtrial in range(0, self.subtrials):
                flash = self.presentation.execute_sub_trial()
                # print("generated flash sequence with length: " + str(len(flash)))
                print("flash sequence content: " + str(flash))

                if trial == 0 and subtrial == 0:
                    self.flashseq = np.zeros(
                        (self.trials, self.subtrials, len(flash)))
                if subtrial == 0:
                    self.onsets.append([])

                self.flashseq[trial, subtrial, :] = [int(i[0]) for i in flash]
                self.onsets[trial].append([int(i[1]) for i in flash])
                print("flashseq" + str(self.flashseq.shape))

    def saveData(self):
        np.save(self.data_prefix + "data", self.lslrec.data)
        np.save(self.data_prefix + "timestamps", self.lslrec.timeStamps)
        np.save(self.data_prefix + "targets", self.targets)
        np.save(self.data_prefix + "onsets", self.onsets)
        np.save(self.data_prefix + "flashseq", self.flashseq)
        np.save(self.data_prefix + "srate", self.lslrec.srate)
        np.save(self.data_prefix + "presentation_mode", self.mode)
        print("saved data to " + self.data_prefix)