Beispiel #1
0
def read(queue, mwm_pipeend, display_freq, episode_duration):
    #used for data acquisition timing
    counter = 0
    record_times = []

    #mwm collects data at approximately 512 Hz. Can vary though. That's why we need the trim.
    trim_size = (episode_duration - .4) * 508
    print("episode_duration:", episode_duration)
    episode_data = []
    #creates a new mindwave mobile object
    mwm_reader = MindwaveDataPointReader()
    mwm_reader.start()

    #finds the start signal
    while True:
        data_point = mwm_reader.readNextDataPoint()
        if data_point.__class__ is StartCommand:
            print("Start sequence received, signaling animation...")
            #once the start command is received from the mwm, the start signal is sent through the pipe to the animation process
            mwm_pipeend.send([True])
            break
    epi_type = mwm_pipeend.recv()[0]

    print("\tCommencing data acquisition at", time.time())
    #for as long as the episode is happening, read data from mwm. For some reason, mwm closes too late. Need early stopping
    #that's why I subtract .4 seconds from the end_time here
    end_time = (time.time() + episode_duration - .4) - .1
    while time.time() < end_time:
        data_point = mwm_reader.readNextDataPoint()
        if (data_point.__class__ is RawDataPoint):
            episode_data.append(data_point._readRawValue())
            if (display_freq):
                current_time = time.time()
                record_times.append(current_time)
                counter += 1
                if (counter == 240):
                    l = np.average(np.diff(record_times))
                    print("\t\tmwm:", 1 / l, "Hz")
                    record_times = []
                    counter = 0
    print("\tClosing mwm stream at", time.time())

    #get the episode type from the environment
    # print("trimming ", len(episode_data) - int(trim_size), "readings")
    # trim the episode data so it's always a constant length
    print("trimming:", len(episode_data) - trim_size)
    episode_data = episode_data[:int(trim_size)]
    episode_data_df = pd.DataFrame().append([episode_data])
    episode_data_df['episode_type'] = np.array([epi_type])

    #close and delete mwm
    mwm_reader.end()
    del mwm_reader
    #when the episode is finished, the data gathered by the recorder device is accessed and placed in the queue so the parent process can obtain it
    queue.put(episode_data_df)
def read(queue, mwm_pipeend, display_freq, episode_duration,
         num_episodes):  #num_episodes
    counter = 0
    record_times = []
    current_episode = 0
    trim_size = (episode_duration - .4) * 508 - 20
    trial_data_df = pd.DataFrame()

    # creates a new mindwave mobile object
    mwm_reader = MindwaveDataPointReader()
    mwm_reader.start()

    # finds the start signal
    while True:
        data_point = mwm_reader.readNextDataPoint()
        if data_point.__class__ is StartCommand:
            print("Start sequence received.")
            break

    start_time = time.time()
    #idles for 3 seconds to jump past annoying start spike
    while (time.time() < start_time + 12):
        mwm_reader.readNextDataPoint()
        if (display_freq):
            current_time = time.time()
            record_times.append(current_time)
            counter += 1
            if (counter == 512):
                l = np.average(np.diff(record_times))
                print("\t\tmwm idling")
                record_times = []
                counter = 0

    # once the start command is received from the mwm, the start signal is sent through the pipe to the animation process
    mwm_pipeend.send(["start_trial"])
    print("Startup spike passed. Trial begins.\n")

    while (current_episode < num_episodes):
        counter = 0
        record_times = []
        #used for data acquisition timing
        episode_data = []
        episode_reading_times = []
        epi_type = mwm_pipeend.recv()[0]
        mwm_reader.clearBuffer()
        # mwm_reader.clearBufferV2()
        mwm_pipeend.send(["buffer_cleared"])
        #for as long as the episode is happening, read data from mwm. For some reason, mwm closes too late. Need early stopping
        #that's why I subtract .4 seconds from the end_time here
        end_time = (time.time() + episode_duration - .4) - .15
        print("\tCommencing data acquisition at", time.time())
        #record data for length of episode
        while time.time() < end_time:
            data_point = mwm_reader.readNextDataPoint()
            if (data_point.__class__ is RawDataPoint):
                episode_data.append(data_point._readRawValue())
                episode_reading_times.append(time.time())
                if (display_freq):
                    current_time = time.time()
                    record_times.append(current_time)
                    counter += 1
                    if (counter == 240):
                        l = np.average(np.diff(record_times))
                        print("\t\tmwm:", int(1 / l), "Hz")
                        record_times = []
                        counter = 0
        print("\tEnding data acquisition at", time.time())

        correct_index = 1024  #this value represents the index at which Pacman initially moves
        #receives the time at which pacman makes his move from the environment
        action_time = mwm_pipeend.recv()[0]
        #finds the index closest in time to pacman's move time
        action_index = episode_reading_times.index(
            min(episode_reading_times, key=lambda x: abs(x - action_time)))

        #adds dummy data to front of episode_data or removes offset number of readings so that the critical points are aligned
        offset = action_index - correct_index
        if (offset < 0):
            dummy = [0] * abs(offset)
            episode_data = dummy + episode_data
        elif (offset > 0):
            episode_data = episode_data[offset:]

        to_trim = int(len(episode_data) - trim_size)
        print("\t\ttrimming:", to_trim, "readings")
        episode_data = episode_data[:int(trim_size)]
        episode_data_df = pd.DataFrame().append([episode_data])
        episode_data_df['episode_type'] = np.array([epi_type])
        episode_data_df['episode_num'] = np.array([current_episode])
        episode_data_df['action_index'] = np.array([action_index])
        episode_data_df['trimmed_data'] = np.array([to_trim])
        episode_data_df['win'] = np.array([epi_type in [0, 3]])

        print("\tpredicting...")
        prediction = predict(episode_data_df)
        mwm_pipeend.send(prediction)
        print("prediction sent")

        #predict if episode data df is corrupt
        if (action_index < 950 or action_index > 1100):
            episode_data_df['is_corrupt'] = np.array([1])
        elif (to_trim > 100 or to_trim < 0):
            episode_data_df['is_corrupt'] = np.array([1])
        else:
            episode_data_df['is_corrupt'] = np.array([0])

        # append to trial data df
        trial_data_df = pd.concat([trial_data_df, episode_data_df])
        print("Episode finished. \n\n")
        #idle until animation sends finished animation signal
        # while(not mwm_pipeend.recv()):
        #     mwm_reader.readNextDataPoint()
        #     if (display_freq):
        #         current_time = time.time()
        #         record_times.append(current_time)
        #         counter += 1
        #         if (counter == 240):
        #             l = np.average(np.diff(record_times))
        #             print("\t\tmwm:", 1 / l, "Hz")
        #             record_times = []
        #             counter = 0
        current_episode += 1
    #close and delete mwm
    mwm_reader.end()
    del mwm_reader
    #when the episode is finished, the data gathered by the recorder device is accessed and placed in the queue so the parent process can obtain it
    queue.put(trial_data_df)