Esempio n. 1
0
class Application(tk.Frame):

    analyzer = gda.GazeDataAnalyzer()

    session_path = "session_data/" + datetime.datetime.now().strftime(
        "%Y-%m-%d %H.%M.%S") + "/"

    config_filename = session_path + "config.csv"
    test_folder = None

    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.master = master

        # Get width and height of screen
        self.screen_width = self.master.winfo_screenwidth()
        self.screen_height = self.master.winfo_screenheight()
        self.screen_size_inches = 27

        self.pack(fill="both", expand=True)

        # Initialize tobii_controller with configurations
        self.controller = tobii_controller(self.screen_width,
                                           self.screen_height)
        self.controller.subscribe_dict()

        self.status_admin_process = Process(
            target=self.controller.show_status_admin(screen=0))
        self.status_admin_process.start()

        self.controller.show_status(screen=1)

        try:
            os.makedirs(self.session_path)
        except Exception:
            # directory already exists
            pass

        self.config_setup()

    def config_setup(self):
        self.panel_config = tk.Frame(self)

        fields = ["Age (Months)", "Sex", "Distance to screen (cm)"]
        values = ["12", "M", "60"]

        entries = []
        for field, value in zip(fields, values):
            row = tk.Frame(self.panel_config)
            label = tk.Label(row, width=20, text=field, anchor='w')
            entry = tk.Entry(row)
            entry.insert(tk.END, value)
            row.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
            label.pack(side=tk.LEFT)
            entry.pack(side=tk.RIGHT, expand=True, fill=tk.X)
            entries.append((field, entry))

        btn_config_save = tk.Button(self.panel_config)
        btn_config_save["text"] = "Save configuration"
        btn_config_save["fg"] = "black"
        btn_config_save["bg"] = "#b2b2b2"
        btn_config_save["command"] = lambda e=entries: self.config_save(e)
        btn_config_save.pack(side=tk.LEFT, padx=5, pady=10)

        self.panel_config.pack(side=tk.TOP, pady=(10, 10))

    def config_save(self, entries):

        # PYTHON 2.x
        with open(self.config_filename, mode='wb') as csv_file:
            field_names = [row[0] for row in entries]
            entry_texts = [row[1].get() for row in entries]

            field_names.extend([
                "Screen size (inches)", "Screen width (px)",
                "Screen height (px)"
            ])
            entry_texts.extend([
                self.screen_size_inches, self.screen_width, self.screen_height
            ])

            config_writer = csv.DictWriter(csv_file,
                                           fieldnames=field_names,
                                           delimiter=";")
            config_writer.writeheader()

            config_dict = {}
            for f, e in zip(field_names, entry_texts):
                config_dict[f] = e

            config_writer.writerow(config_dict)

            self.controller.set_dist_to_screen(
                config_dict["Distance to screen (cm)"])

        print("Configurations saved")
        self.panel_config.pack_forget()
        self.show_main_panel()

    def show_main_panel(self):

        self.btn_test = tk.Button(self)
        self.btn_test["text"] = "TEST"
        self.btn_test["fg"] = "white"
        self.btn_test["bg"] = "#000000"
        self.btn_test["command"] = self.test
        self.btn_test.pack(side=tk.TOP, pady=(0, 10))

        self.btn_test1 = tk.Button(self)
        self.btn_test1["text"] = "TEST - Fixation"
        self.btn_test1["fg"] = "white"
        self.btn_test1["bg"] = "#000000"
        self.btn_test1["command"] = self.test_fixation
        self.btn_test1.pack(side=tk.TOP, pady=(0, 10))

        self.btn_test2 = tk.Button(self)
        self.btn_test2["text"] = "TEST - Pursuit (linear)"
        self.btn_test2["fg"] = "white"
        self.btn_test2["bg"] = "#000000"
        self.btn_test2["command"] = lambda t="linear": self.test_pursuit(t)
        self.btn_test2.pack(side=tk.TOP, pady=(0, 10))

        self.btn_test3 = tk.Button(self)
        self.btn_test3["text"] = "TEST - Pursuit (spiral)"
        self.btn_test3["fg"] = "white"
        self.btn_test3["bg"] = "#000000"
        self.btn_test2["command"] = lambda t="spiral": self.test_pursuit(t)
        self.btn_test3.pack(side=tk.TOP, pady=(0, 10))

        self.btn_default_test = self.make_test_button("Test default",
                                                      "default")
        self.btn_2p_test = self.make_test_button("Test 2-point", "custom_2p")
        self.btn_5p_test = self.make_test_button("Test 5-point", "custom_5p")
        self.btn_5p_img_test = self.make_test_button("Test 5-point (image)",
                                                     "custom_5p_img")

        self.btn_show_status = tk.Button(self)
        self.btn_show_status["text"] = "Check eye position"
        self.btn_show_status["fg"] = "white"
        self.btn_show_status["bg"] = "#2196F3"
        self.btn_show_status["command"] = self.show_status

        self.btn_shutdown = tk.Button(self)
        self.btn_shutdown["text"] = "Shutdown"
        self.btn_shutdown["fg"] = "white"
        self.btn_shutdown["bg"] = "#f44336"
        self.btn_shutdown["command"] = self.client_exit

        # pack it all
        self.btn_default_test.pack(side=tk.TOP, pady=(10, 10))
        self.btn_2p_test.pack(side=tk.TOP, pady=(0, 10))
        self.btn_5p_test.pack(side=tk.TOP, pady=(0, 10))
        self.btn_5p_img_test.pack(side=tk.TOP, pady=(0, 10))
        self.btn_show_status.pack(side=tk.TOP, pady=(0, 10))
        self.btn_shutdown.pack(side=tk.TOP)

    def test(self):
        self.controller.make_psycho_window()
        self.custom_calibration(5, "img")
        self.controller.close_psycho_window()

    def test_fixation(self):
        self.controller.make_psycho_window()
        #        self.controller.start_fixation_exercise(positions=[(-0.5,-0.5), (0.5,-0.5), (-0.5, 0.5), (0.5, 0.5), (0.0, 0.0)], stimuli_paths=["stimuli/star_yellow.png"])
        self.controller.start_fixation_exercise_animate_transition(
            positions=[(-0.5, -0.5), (0.5, -0.5), (-0.5, 0.5), (0.5, 0.5),
                       (0.0, 0.0)],
            stimuli_paths=["stimuli/star_yellow.png"])
        self.controller.close_psycho_window()

    def test_pursuit(self, path_type):
        self.controller.make_psycho_window()

        #        if path_type == "linear":
        #            self.controller.start_pursuit_exercise(pathing="linear", positions=[(-0.5,-0.5), (0.3, 0.5), (0.5, -0.5), (0.0, 0.0)], stimuli_paths=["stimuli/smiley_yellow.png"])
        #        elif path_type == "spiral":
        #            self.controller.start_pursuit_exercise(pathing="spiral", positions=[(-0.7,0.0), (0.0, 0.0)], stimuli_paths=["stimuli/smiley_yellow.png"])
        self.controller.start_pursuit_exercise(
            pathing="linear",
            positions=[(-0.5, -0.5), (0.3, 0.5), (0.5, -0.5), (0.0, 0.0)],
            stimuli_paths=["stimuli/smiley_yellow.png"])
        self.controller.close_psycho_window()

    def test_pursuit_horizontal(self):
        self.controller.make_psycho_window()
        self.controller.start_pursuit_exercise(
            pathing="linear",
            positions=[(-0.85, -0.5), (-0.5, 0.7), (0.0, 0.7), (0.1, -0.7),
                       (0.6, -0.7), (0.85, 0.5)],
            stimuli_paths=["stimuli/smiley_yellow.png"])
        self.controller.close_psycho_window()

    def make_test_button(self, title, cal_type):
        btn = tk.Button(self)
        btn["text"] = title
        btn["fg"] = "white"
        btn["bg"] = "#4CAF50"
        btn["command"] = lambda t=cal_type: self.run_test(t)
        return btn

    def run_test(self, cal_type):
        self.controller.make_psycho_window()

        self.test_folder = "test_" + cal_type + "/"

        self.controller.play_sound()
        self.controller.flash_screen()

        if cal_type == "default":
            pass
        elif cal_type == "custom_2p":
            self.custom_calibration(2, "img")
        elif cal_type == "custom_5p":
            self.custom_calibration(5, "img")
        elif cal_type == "custom_5p_img":
            self.custom_calibration(5, "img")

        self.controller.start_fixation_exercise_animate_transition(
            positions=[(-0.5, -0.5), (0.5, -0.5), (-0.5, 0.5), (0.5, 0.5),
                       (0.0, 0.0)],
            stimuli_paths=["stimuli/smiley_yellow.png"])
        self.store_data("training_fixation")

        #        self.controller.flash_screen()
        #        self.controller.start_fixation_exercise(positions=[(-0.5,-0.5), (0.5,-0.5), (-0.5, 0.5), (0.5, 0.5), (0.0, 0.0)], stimuli_paths=["stimuli/star_yellow.png"])
        #        self.controller.start_fixation_exercise_animate_transition(positions=[(-0.8,-0.8), (-0.8,-0.4), (-0.8, 0.0), (-0.8, 0.4), (-0.8, 0.8), (-0.4,-0.8), (-0.4,-0.4), (-0.4, 0.0), (-0.4, 0.4), (-0.4, 0.8), (0.0,-0.8), (0.0,-0.4), (0.0, 0.0), (0.0, 0.4), (0.4, 0.8), (0.4,-0.8), (0.4,-0.4), (0.4, 0.0), (0.4, 0.4), (0.4, 0.8), (0.8,-0.8), (0.8,-0.4), (0.8, 0.0), (0.8, 0.4), (0.8, 0.8)], stimuli_paths=["stimuli/star_yellow.png"], fixation_duration = 1.5)
        #        self.store_data("training_fixation_2")

        self.controller.start_pursuit_exercise(
            pathing="circle",
            positions=[(-0.7, 0.0), (0.0, 0.0)],
            stimuli_paths=["stimuli/smiley_yellow.png"])
        self.store_data("training_pursuit_circle")

        self.controller.start_pursuit_exercise(
            pathing="circle",
            positions=[(-0.7, 0.0), (0.0, 0.0)],
            stimuli_paths=["stimuli/smiley_yellow.png"],
            reverse=True)
        self.store_data("training_pursuit_circle_revert")
        positions = [(-0.7, 0.0), (0.0, 0.0)]
        pos = []
        for p in positions:
            pos.append(self.controller.get_tobii_pos(p))
        print(pos)

        #        self.controller.flash_screen()
        self.controller.start_pursuit_exercise(
            pathing="linear",
            positions=[(-0.5, -0.5), (0.3, 0.5), (0.5, -0.5), (0.0, 0.0)],
            stimuli_paths=["stimuli/smiley_yellow.png"])
        #        self.controller.start_pursuit_exercise(pathing="linear", positions=[(-0.85,-0.5), (-0.5, 0.7), (0.0, 0.7), (0.1, -0.7), (0.6, -0.7), (0.85, 0.5)], stimuli_paths=["stimuli/smiley_yellow.png"])

        self.store_data("training_pursuit_linear")

        #        self.controller.flash_screen()
        self.controller.start_pursuit_exercise(
            pathing="spiral",
            positions=[(-0.7, 0.0), (0.0, 0.0)],
            stimuli_paths=["stimuli/smiley_yellow.png"])
        self.store_data("training_pursuit_spiral")
        self.controller.pause_sound()

        self.controller.close_psycho_window(screen=1)

    def show_status(self, screen=1):
        self.controller.show_status(screen=screen)

    def custom_calibration(self, num_points, stim_type="default"):

        # we can only check if there is an existing eye tracking device.
        # this will still fail whenever the device is there but turned off
        # TobiiProSDK does not support activity checks this for python it seems..
        self.controller.start_custom_calibration(num_points,
                                                 stim_type=stim_type)

    def store_data(self, testname):

        # write data to file
        try:  # just in case we run exercise before calibration
            os.makedirs(self.session_path + self.test_folder)
        except Exception:
            # directory already exists
            pass

        filename = self.session_path + self.test_folder + testname + ".csv"

        # PYTHON 2.x
        with open(filename, mode='wb') as gaze_data_file:

            field_names = [data for data in self.controller.gaze_params]
            gaze_data_writer = csv.DictWriter(gaze_data_file,
                                              fieldnames=field_names,
                                              delimiter=";")

            gaze_data_writer.writeheader()
            for gaze_data in self.controller.global_gaze_data:
                gaze_data_writer.writerow(gaze_data)

    def client_exit(self):
        print("Shutting down")
        self.controller.unsubscribe_dict()
        self.quit()
Esempio n. 2
0
class Application(tk.Frame):

    analyzer = gda.GazeDataAnalyzer()

    session_path = "session_data/" + datetime.datetime.now().strftime(
        "%Y-%m-%d %H.%M.%S/")

    cal_file_index = 0
    training_file_index = 0

    config_filename = session_path + "config.csv"

    cal_path = session_path + "calibrations/"

    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.master = master

        # Get width and height of screen
        self.screen_width = self.master.winfo_screenwidth()
        self.screen_height = self.master.winfo_screenheight()

        self.pack(fill="both", expand=True)
        self.create_widgets()

        # Initialize tobii_controller with configurations
        self.controller = tobii_controller(self.screen_width,
                                           self.screen_height)
        self.controller.show_status()

        try:
            os.makedirs(self.cal_path)
        except Exception:
            # directory already exists
            pass

    def create_widgets(self):

        config_fields = [
            "Age (Months)", "Sex", "Severity (1-5)", "Screen size (inches)",
            "Distance to screen (cm)"
        ]
        config_values = ["12", "M", "1", "27", "60"]
        self.config_panel = tk.Frame(self)
        self.config_setup(self.config_panel, config_fields, config_values)
        self.config_panel.pack(side=tk.TOP, pady=(self.screen_height / 2, 0))

        self.calibrate_button = tk.Button(self)
        self.calibrate_button["text"] = "Make transformation"
        self.calibrate_button["fg"] = "white"
        self.calibrate_button["bg"] = "#FFA500"
        self.calibrate_button["command"] = self.start_calibration_exercise

        self.training_fixation_button = tk.Button(self)
        self.training_fixation_button["text"] = "Start fixation exercise"
        self.training_fixation_button["fg"] = "white"
        self.training_fixation_button["bg"] = "#4CAF50"
        self.training_fixation_button[
            "command"] = lambda training_type="fixation": self.training_exercise(
                training_type)

        self.training_pursuit_button = tk.Button(self)
        self.training_pursuit_button["text"] = "Start pursuit exercise"
        self.training_pursuit_button["fg"] = "white"
        self.training_pursuit_button["bg"] = "#4CAF50"
        self.training_pursuit_button[
            "command"] = lambda training_type="pursuit": self.training_exercise(
                training_type)

        self.custom_cal_2_button = tk.Button(self)
        self.custom_cal_2_button["text"] = "Custom 2p calibration"
        self.custom_cal_2_button["fg"] = "white"
        self.custom_cal_2_button["bg"] = "#2196F3"
        self.custom_cal_2_button[
            "command"] = lambda n=2: self.custom_calibration(n)

        self.custom_cal_5_button = tk.Button(self)
        self.custom_cal_5_button["text"] = "Custom 5p calibration"
        self.custom_cal_5_button["fg"] = "white"
        self.custom_cal_5_button["bg"] = "#2196F3"
        self.custom_cal_5_button[
            "command"] = lambda n=5: self.custom_calibration(n)

        self.eye_pos_button = tk.Button(self)
        self.eye_pos_button["text"] = "Check eye position"
        self.eye_pos_button["fg"] = "white"
        self.eye_pos_button["bg"] = "#2196F3"
        self.eye_pos_button["command"] = self.check_eye_position

        self.shutdown_button = tk.Button(self)
        self.shutdown_button["text"] = "Shutdown"
        self.shutdown_button["fg"] = "white"
        self.shutdown_button["bg"] = "#f44336"
        self.shutdown_button["command"] = self.client_exit

    def config_setup(self, root, fields, values):
        entries = []
        for field, value in zip(fields, values):
            row = tk.Frame(root)
            label = tk.Label(row, width=15, text=field, anchor='w')
            entry = tk.Entry(row)
            entry.insert(tk.END, value)
            row.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
            label.pack(side=tk.LEFT)
            entry.pack(side=tk.RIGHT, expand=True, fill=tk.X)
            entries.append((field, entry))
        btn_config_save = tk.Button(root)
        btn_config_save["text"] = "Save configuration"
        btn_config_save["fg"] = "black"
        btn_config_save["bg"] = "#b2b2b2"
        btn_config_save["command"] = lambda e=entries: self.config_save(e)
        btn_config_save.pack(side=tk.LEFT, padx=5, pady=10)

    def config_save(self, entries):

        # PYTHON 2.x
        with open(self.config_filename, mode='wb') as csv_file:
            field_names = [row[0] for row in entries]
            entry_texts = [row[1].get() for row in entries]

            field_names.extend(["Screen width (px)", "Screen height (px)"])
            entry_texts.extend([self.screen_width, self.screen_height])

            config_writer = csv.DictWriter(csv_file,
                                           fieldnames=field_names,
                                           delimiter=";")
            config_writer.writeheader()

            self.config_dict = {}
            for f, e in zip(field_names, entry_texts):
                self.config_dict[f] = e

            config_writer.writerow(self.config_dict)

        print("Configurations saved")
        self.config_panel.pack_forget()
        self.show_main_panel()

        self.controller.set_dist_to_screen(
            self.config_dict["Distance to screen (cm)"])

    def show_main_panel(self):
        self.calibrate_button.pack(side=tk.TOP,
                                   pady=(self.screen_height / 2 - 50, 10))
        self.training_fixation_button.pack(side=tk.TOP, pady=(0, 10))
        self.training_pursuit_button.pack(side=tk.TOP, pady=(0, 10))
        self.custom_cal_2_button.pack(side=tk.TOP, pady=(0, 10))
        self.custom_cal_5_button.pack(side=tk.TOP, pady=(0, 10))
        self.eye_pos_button.pack(side=tk.TOP, pady=(0, 10))
        self.shutdown_button.pack(side=tk.TOP)

    def hide_main_panel(self):
        self.shutdown_button.pack_forget()
        self.calibrate_button.pack_forget()
        self.training_pursuit_button.pack_forget()
        self.training_fixation_button.pack_forget()
        self.custom_cal_2_button.pack_forget()
        self.custom_cal_5_button.pack_forget()
        self.eye_pos_button.pack_forget()

    def check_eye_position(self):
        self.controller.show_status()

    def training_exercise(self, training_type="fixation"):

        # Start eye traking

        if training_type == "fixation":
            self.controller.start_fixation_exercise()

        elif training_type == "pursuit":
            self.controller.start_pursuit_exercise(pathing="spiral")


#    def training_exercise(self):
#        print("Simulation ended")
#
#        # Stop eye tracking
#        if self.controller.eyetracker != None:
#            pass
#            self.eye_tracking.end_gaze_tracking()
#
#            self.training_file_index = self.training_file_index + 1
#
#            training_filename = self.session_path + "training_with_cal_" + str(self.cal_file_index) + "/training_" + str(self.training_file_index) + ".csv"
#
#            # PYTHON 2.x
#            with open(training_filename, mode='wb') as gaze_data_file:
#
#                field_names = [data for data in self.eye_tracking.gaze_params]
#                gaze_data_writer = csv.DictWriter(gaze_data_file, fieldnames=field_names, delimiter=";")
#
#                gaze_data_writer.writeheader()
#                for gaze_data in self.eye_tracking.global_gaze_data:
#                    gaze_data_writer.writerow(gaze_data)
#
#            try:
#                self.analyzer.analyze(training_filename)
#            except:
#                print("Bad data obtained")

# Hide canvas
# Show button after exercise
#self.show_main_panel()

    def start_calibration_exercise(self):
        self.controller.make_transformation()

    def custom_calibration(self, num_points):

        # we can only check if there is an existing eye tracking device.
        # this will still fail whenever the device is there but turned off
        # TobiiProSDK does not support activity checks this for python it seems..
        self.controller.start_custom_calibration(num_points)

    def client_exit(self):
        print("Shutting down")
        self.quit()
Esempio n. 3
0
# Run analyse on
type_of_cal = "default"
#type_of_cal = "custom_2p"
#type_of_cal = "custom_5p"

# Session to run
session_folder = "ctrl_group_2_louise"
#session_folder = "infant_d25_gudrun_5m"

# Setting path and files
session_path = "session_data/" + session_folder + "/"
test_folder = session_path + "test_" + type_of_cal + "/"
config_filename = session_path + "config.csv"
training_filename = test_folder + "training_fixation.csv"

analyzer = gda.GazeDataAnalyzer()

print("\nSimulate cross validation")
analyzer.cross_validation(config_filename,
                          training_filename,
                          "dbscan_fixation",
                          k=5)

#print("\nTEST DATA - FIXATION")
#training_filename = test_folder + "training_fixation.csv"
#analyzer.analyze(training_filename, "dbscan_fixation", "values")
#
#print("\nTEST DATA - PURSUIT (CIRCLE)")
#training_filename = test_folder + "training_pursuit_circle.csv"
#analyzer.analyze(training_filename, "dbscan_pursuit", "values")
#
Esempio n. 4
0
def analyze(session_folder):

    try:
        print("Running for " + session_folder)
        print("------------------------")

        # Setting path and files
        session_path = "session_data/" + session_folder + "/"
        test_folder = session_path + "test_" + type_of_cal + "/"
        config_filename = session_path + "config.csv"
        #        cal_filename = test_folder + "training_fixation.csv"
        cal_filename = test_folder + "training_fixation_2.csv"
        #        cal_filename = test_folder + "training_pursuit_circle.csv"
        #        cal_filename = test_folder + "training_pursuit_linear.csv"
        #        cal_filename = test_folder + "training_pursuit_spiral.csv"

        #        remove_outliers = True
        remove_outliers = False

        print("")
        print("Computing analyze linear transformation")
        print("------------------------")

        analyzer = gda.GazeDataAnalyzer()
        print("\nSETUP TRANSFORMATION")
        #        analyzer.cross_validation(config_filename, cal_filename, "dbscan_fixation", k = 2)
        #        analyzer.cross_validation(config_filename, cal_filename, "dbscan_pursuit", k = 5)
        analyzer.setup_affine2(config_filename, cal_filename,
                               "dbscan_fixation")
        #        analyzer.setup_affine2(config_filename, cal_filename, "dbscan_pursuit")
        #        print("\nTRAINING DATA")
        #        analyzer.analyze(cal_filename, "dbscan_fixation")

        try:
            print("\nTEST DATA - FIXATION")
            training_filename = test_folder + "training_fixation.csv"
            angle_avg, angle_avg_corrected = analyzer.analyze_affine2(
                training_filename,
                "dbscan_fixation",
                "values",
                remove_outliers=remove_outliers)
            #            if len(angle_avg) < (5*90*0.3):
            #                raise ValueError('Not enough data')
            fixation_deg_raw.append(np.mean(angle_avg))
            fixation_deg_cor.append(np.mean(angle_avg_corrected))
        except:
            print("-----------------------------")
            print("SKIPPING FIXATION")
            print("-----------------------------")
            fixation_deg_raw.append(0)
            fixation_deg_cor.append(0)

        try:
            print("\nTEST DATA - FIXATION_2")
            training_filename = test_folder + "training_fixation_2.csv"
            angle_avg, angle_avg_corrected = analyzer.analyze_affine2(
                training_filename,
                "dbscan_fixation",
                "values",
                remove_outliers=remove_outliers)

            #            if len(angle_avg) < (5*90*0.3):
            #                raise ValueError('Not enough data')
            fixation_2_deg_raw.append(np.mean(angle_avg))
            fixation_2_deg_cor.append(np.mean(angle_avg_corrected))
        except:
            print("-----------------------------")
            print("SKIPPING FIXATION 2")
            print("-----------------------------")
            fixation_2_deg_raw.append(0)
            fixation_2_deg_cor.append(0)

        try:
            print("\nTEST DATA - PURSUIT (CIRCLE)")
            training_filename = test_folder + "training_pursuit_circle.csv"
            angle_avg, angle_avg_corrected = analyzer.analyze_affine2(
                training_filename,
                "dbscan_pursuit",
                "values",
                remove_outliers=remove_outliers)

            #            if len(angle_avg) < (5*90*0.3):
            #                raise ValueError('Not enough data')

            pursuit_circle_deg_raw.append(np.mean(angle_avg))
            pursuit_circle_deg_cor.append(np.mean(angle_avg_corrected))
        except:
            print("-----------------------------")
            print("SKIPPING PURSUIT CIRCLE")
            print("-----------------------------")
            pursuit_circle_deg_raw.append(0)
            pursuit_circle_deg_cor.append(0)

        try:
            print("\nTEST DATA - PURSUIT (CIRCLE REVERT)")
            training_filename = test_folder + "training_pursuit_circle_revert.csv"
            angle_avg, angle_avg_corrected = analyzer.analyze_affine2(
                training_filename,
                "dbscan_pursuit",
                "values",
                remove_outliers=remove_outliers)

            #            if len(angle_avg) < (5*90*0.3):
            #                raise ValueError('Not enough data')

            pursuit_circle_revert_deg_raw.append(np.mean(angle_avg))
            pursuit_circle_revert_deg_cor.append(np.mean(angle_avg_corrected))
        except:
            print("-----------------------------")
            print("SKIPPING PURSUIT CIRCLE REVERT")
            print("-----------------------------")
            pursuit_circle_revert_deg_raw.append(0)
            pursuit_circle_revert_deg_cor.append(0)

        try:
            print("\nTEST DATA - PURSUIT (LINEAR)")
            training_filename = test_folder + "training_pursuit_linear.csv"
            angle_avg, angle_avg_corrected = analyzer.analyze_affine2(
                training_filename,
                "dbscan_pursuit",
                "values",
                remove_outliers=remove_outliers)

            #            if len(angle_avg) < (5*90*0.3):
            #                raise ValueError('Not enough data')

            pursuit_linear_deg_raw.append(np.mean(angle_avg))
            pursuit_linear_deg_cor.append(np.mean(angle_avg_corrected))
        except:
            print("-----------------------------")
            print("SKIPPING PURSUIT LINEAR")
            print("-----------------------------")
            pursuit_linear_deg_raw.append(0)
            pursuit_linear_deg_cor.append(0)

        try:
            print("\nTEST DATA - PURSUIT (SPIRAL)")
            training_filename = test_folder + "training_pursuit_spiral.csv"
            angle_avg, angle_avg_corrected = analyzer.analyze_affine2(
                training_filename,
                "dbscan_pursuit",
                "values",
                remove_outliers=remove_outliers)

            #            if len(angle_avg) < (5*90*0.3):
            #                raise ValueError('Not enough data')

            pursuit_spiral_deg_raw.append(np.mean(angle_avg))
            pursuit_spiral_deg_cor.append(np.mean(angle_avg_corrected))
        except:
            print("-----------------------------")
            print("SKIPPING PURSUIT SPIRAL")
            print("-----------------------------")
            pursuit_spiral_deg_raw.append(0)
            pursuit_spiral_deg_cor.append(0)

        print("")
    except:
        print("-----------------------------")
        print("SKIPPING " + session_folder)
        print("-----------------------------")