diff --git a/README.md b/README.md
deleted file mode 100644
index 9a71486936c7602a15fb67101aa2dc3b8f7ec18c..0000000000000000000000000000000000000000
--- a/README.md
+++ /dev/null
@@ -1,304 +0,0 @@
-# Modeling Human Performance Psych 139D Winter 2025
-
-## `EPICpy` & `epiccoder` Installation
-
-### <font color="blue">**Operating System Requirements**</font>
-
-Although we have not tested widely, the following setups should work:
-
-- Windows 10 or Windows 11
-- MacOS Monteray and later (Intel and ARM based chips)
-- Linux with Ubuntu based distros version 20.10 and later
-
-Linux versions earlier than 20.10 _could_ work, but `ldd --version` would have to print some version >= 2.32, and you might still end up having to install several missing libraries.
-
-### <font color="blue">**Installing Prerequisites**</font>
-
-Installing these applications requires the following utilities to be installed on your computer:
-
-- curl
-- git
-- uv
-- Python 3.10 (MacOS and Linux) or Python 3.9 (Windows)
-
-**NOTE**: The lab machines in SS1 Mac Lab already have prerequisites, so you can skip this section.
-On your own machine, you may have to install one or more of them.
-
-**Installing `curl`** 
-
-`curl` is installed by default on MacOS and Windows. Some Linux distributions come with `curl`, and others (especially "minimal" distributions) may not.
-
-If this check reports that `curl` is not installed:
-
-```bash
-curl --version
-```
-
-then you can install curl with your package manager, e.g.:
-
-```bash
-sudo apt install curl
-```
-
-**Installing `git`** 
-
-`git` is not typically installed by default.
-
-If this check reports that `git` is not installed:
-
-```bash
-git --version
-```
-
-then you may need to install `git`. In all most cases, you can go here: https://git-scm.com/downloads and use the installer that goes with your operating system. 
-
-If you prefer a command-line solutions:
-
-- MacOS:
-    1. Install [homebrew](https://brew.sh/).
-    2. run `brew install git`
-- Windows:
-    1. Install [scoop](https://scoop.sh/)
-    2. run `scoop install git`
-- Linux:
-    1. run `sudo apt install git` (replace `apt install` with whatever works on your system)
-
-**Installing `uv`**
-
-`uv` is not automatically installed on any operating system. 
-
-If this check reports that `uv` is not installed:
-
-```bash
-uv --version
-```
-
-Then you can see the installation instructions for on the [uv installation webpage](https://docs.astral.sh/uv/getting-started/installation/), which currently suggests use these commands:
-
-MacOS and Linux
-
-```bash
-curl -LsSf https://astral.sh/uv/install.sh | sh
-```
-
-Windows
-
-```bash
-powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
-```
-
-**Installing `python`**
-
-Your operating system may already have one or more version of Python installed, or it may have none.
-
-Assuming you have `uv` installed, try this command:
-
-```bash
-uv python list --only-installed
-```
-
-Here is what I get on my Linux system:
-
-    cpython-3.12.7-linux-x86_64-gnu   /home/user/.local/share/uv/python/cpython-3.12.7-linux-x86_64-gnu/bin/python3 -> python3.12
-    cpython-3.11.10-linux-x86_64-gnu  /home/user/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/bin/python3 -> python3.11
-    cpython-3.10.12-linux-x86_64-gnu  /usr/bin/python3.10
-    cpython-3.10.12-linux-x86_64-gnu  /usr/bin/python3 -> python3.10
-    cpython-3.10.12-linux-x86_64-gnu  /bin/python3.10
-    cpython-3.10.12-linux-x86_64-gnu  /bin/python3 -> python3.10
-    cpython-3.9.20-linux-x86_64-gnu   /home/user/.local/share/uv/python/cpython-3.9.20-linux-x86_64-gnu/bin/python3 -> python3.9
-
-If you are running _Linux or MacOS_ and you see "3.10" anywhere in the output, then you have a version of Python (i.e., Python 3.10) that you need to install EPICpy.
-If you are running _Windows_ and you see "3.9" anywhere in the output, then you have a version of Python (i.e., Python 3.10) that you need to install EPICpy.
-
-If you don't see the version of Python you need, then it is easy to install it if you have `uv` installed:
-
-MacOS & Linux
-
-```bash
-uv python install 3.10
-```
-
-Windows
-
-```bash
-uv python install 3.9
-```
-
-### <font color="blue">**Downloading Sample Simulations**</font>
-
-To download the sample simulation specifications (_task devices_, associated _rules_, etc.), you can "clone" (or download) them from Prof. Seymour's ucsc git repository:
-
-```bash
-git clone https://git.ucsc.edu/nogard/mhpfiles
-```
-
-This will create a folder called `mhpfiles`. You can see what is in this folder like this:
-
-```bash
-cd mhpfiles
-# Linux & MacOS
-ls
-# Windows
-dir # ls will also work if you are using powershell
-```
-
-### <font color="blue">**Downloading EPICpy and epiccoder [EASY Approach]**</font>
-
-I have created a python program that you can use to install EPICpy and epiccoder easily if you have `uv` installed. 
-
-_NOTE: If you are wisely not in the habit or running random code files, feel free to inspect tool_install.py before taking this next step to ensure that there are no malicious steps. If you want some assurance, consider pasting the code into a LLM and asking it what the code does (or whatever approach you'd like to do to reassure yourself)._
-
-Simply running this command should work on MacOS, Linux, and Windows:
-
-```bash
-uv run tool_install.py
-```
-
-If it fails, it will try to tell you what prerequisite you are missing. Although it requires that you have at least installed `uv` and have _some_ version of Python installed.
-
-
-To ensure that `EPICpy` correctly installed, try running it:
-
-```bash
-EPICpy
-```
-
-If you see the EPICpy graphical interface, it worked!
-
-To ensure that `epiccoder` correctly installed, try running it:
-
-```bash
-epiccoder
-```
-
-If you see the epiccoder graphical interface, it worked!
-
-
-### <font color="blue">**Downloading EPICpy and epiccoder [Manual Approach]**</font>
-
-To install EPICpy and epiccoder manually, first make sure you have successfully installed curl, git, uv, and either Python3.9 (if you run Windows), or Python3.10 (if you run Linux or MacOs).
-
-Next, you need to do the following:
-
-**Obtain the path to python**
-
-```bash
-uv python list --only-installed
-```
-
-Locate one of the lines containing "3.9" (Windows) or "3.10" (MacOS & Linux). 
-For example, from this:
-
-    cpython-3.12.7-linux-x86_64-gnu   /home/nogard/.local/share/uv/python/cpython-3.12.7-linux-x86_64-gnu/bin/python3 -> python3.12
-    cpython-3.11.10-linux-x86_64-gnu  /home/nogard/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/bin/python3 -> python3.11
-    cpython-3.10.12-linux-x86_64-gnu  /usr/bin/python3.10
-    cpython-3.10.12-linux-x86_64-gnu  /usr/bin/python3 -> python3.10
-    cpython-3.10.12-linux-x86_64-gnu  /bin/python3.10
-    cpython-3.10.12-linux-x86_64-gnu  /bin/python3 -> python3.10
-    cpython-3.9.20-linux-x86_64-gnu   /home/nogard/.local/share/uv/python/cpython-3.9.20-linux-x86_64-gnu/bin/python3 -> python3.9
-
-The structure of these entries is this:
-
-[NAME]  [PATH]
-
-or
-
-[NAME]  [PATH] -> [ALIAS]
-
-You want to copy the path. So if I choose 
-
-`cpython-3.9.20-linux-x86_64-gnu   /home/nogard/.local/share/uv/python/cpython-3.9.20-linux-x86_64-gnu/bin/python3 -> python3.9`
-
-I would copy just 
-
-`/home/nogard/.local/share/uv/python/cpython-3.9.20-linux-x86_64-gnu/bin/python3`
-
-If I choose
-
-`cpython-3.10.12-linux-x86_64-gnu  /usr/bin/python3.10`
-
-then I would copy just
-
-`/usr/bin/python3.10`
-
-**Install EPICpy**
-
-Because `EPICpy` has specific requirements for which Python version you use on each operating system, you have to include the appropriate python path in the installation command.
-
-Generically, the syntax would be like this:
-
-```bash
-uv tool install git+https://www.github.com/travisseymour/EPICpy.git --python [YOUR PYTHON PATH]
-```
-
-Specifically, you might enter something like this:
-
-```bash
-# Linux example
-uv tool install git+https://www.github.com/travisseymour/EPICpy.git --python /usr/bin/python3.10
-# MacOS example
-uv tool install git+https://www.github.com/travisseymour/EPICpy.git --python .local/share/uv/python/cpython-3.10.14-macos-x86_64-none/bin/python3
-# Windows example
-uv tool install git+https://www.github.com/travisseymour/EPICpy.git --python AppData\Local\Programs\Python39\python.exe
-```
-
-Of course, **your** python path may be different than these examples. Use the path you copied above as a result of running `uv python list --only-installed`.
-
-
-**Install epiccoder**
-
-`epiccoder` is less picky about which Python version you use. To install it, just run this:
-
-```bash
-uv tool install git+https://www.github.com/travisseymour/epiccoder.git
-```
-
-**Testing Your Installations**
-
-
-To ensure that `EPICpy` correctly installed, try running it:
-
-```bash
-EPICpy
-```
-
-If you see the EPICpy graphical interface, it worked!
-
-To ensure that `epiccoder` correctly installed, try running it:
-
-```bash
-epiccoder
-```
-
-If you see the epiccoder graphical interface, it worked!
-
-### <font color="blue">**Running EPIC Simulations**</font>
-
-**IMPORTANT**: If you just installed `EPICpy` and `epiccoder`, then you have the latest version. However, if you installed EPICpy or epiccoder on your own machine during a previous session, you want to make sure you check for updates before running these tools.
-
-```bash
-uv tool upgrade EPICpy epiccoder
-```
-
-or use this script:
-
-```bash
-uv run update_tools.py
-```
-
-Now, run a simulation:
-
-- To **start** EPICpy, just type `EPICpy` in a terminal.
-- If this is your first time running `EPICpy` and the graphical interface seems wonky, then go to the menu and select `Windows🡆RestoreDefaultLayout`
-- To **load** a model, you'll need to do:
-    - `File🡆LoadDevice` and then locate your device file. A device file is a python file like `choice_device.py`
-    - `File🡆CompileRules` and then locate your rules file. A rules file is a text file like `choicetask_rules_VM.prs`
-- To **run** a model, you'll need to do:
-    - `Run🡆Run`
-- Try to run the Choice task simulation with the "VM" rules 3 times in a row. If you do not see the colorful graph at the end, you may not have the Stats Window open. In the menu, select `Windows🡆ShowStatsWindow`.
-
----
-
-Travis Seymour, PhD
-
-1/24/2025
\ No newline at end of file
diff --git a/README.pdf b/README.pdf
deleted file mode 100644
index 52a0ffa07eef989ee9b254bf1bc2bcf7e38f5d1a..0000000000000000000000000000000000000000
Binary files a/README.pdf and /dev/null differ
diff --git a/bad_detection_rules_v3/bad_detection_rules_v1.prs b/bad_detection_rules_v3/bad_detection_rules_v1.prs
deleted file mode 100644
index 03951428c5f133bbd9d963c356d0b4ed47c1eb22..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v1.prs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal do detection_task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal do detection_task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
-))
-
-
-(TRIAL_start_trial
-If
-(
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Visual_Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(VISUAL_fixation_onset
-If
-(
-	(Step Waitfor Visual_Fixation_Onset)
-	(Visual ?a Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?a)
-	(Add (Tag ?a Fixation_Symbol))
-	(Delete (Step Waitfor Visual_Fixation_Onset))
-	(Add (Step Waitfor Visual_Stimulus_Onset)
-))
-
-(VISUAL_stimulus_onset
-If
-(
-	(Step Waitfor Visual_Stimulus_Onset)
-	(Visual ?a Detection Onset)
-	(Tag ?b Fixation_Symbol)
-	(DIFFERENT ?a ?b)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stimulus_Onset))
-	(Add (Step Make Visual_Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_make visual_response
-If
-(
-	(Step Make Visual_Response)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Visual_Response))
-	(Add (Step Cleanup Memory))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(TRIAL_cleanup_trial
-If 
-(
-	(Step Cleanup Memory)
-	(Tag ?x ?y)
-)
-Then 
-(
-	(Delete (Tag ?x ?y))
-	(Delete (Step Cleanup Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v2.prs b/bad_detection_rules_v3/bad_detection_rules_v2.prs
deleted file mode 100644
index 83318645340964a70e38de54a3b7562685950c4e..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v2.prs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal do detection_task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal do detection_task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
-))
-
-
-(TRIAL_start_trial
-If
-(
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(VISUAL_fixation_onset
-If
-(
-	(Step Waitfor Fixation_Onset)
-	(Visual ?a Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?a)
-	(Add (Tag ?a Fixation_Symbol))
-	(Delete (Step Waitfor Fixation_Onset))
-	(Add (Step Waitfor Visual_Stimulus_Onset))
-))
-
-(VISUAL_stimulus_onset
-If
-(
-	(Step Waitfor Visual_Stimulus_Onset)
-	(Visual ?x Detection Onset)
-	(Tag ?y Fixation_Symbol)
-	(DIFFERENT ?x ?y)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stimulus_Onset))
-	(Add (Step Make Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_make_visual_response
-If
-(
-	(Step Make Response)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Response)
-	(Add (Step Cleanup Memory))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(TRIAL_cleanup_trial
-If 
-(
-	(Step Cleanup Memory)
-	(Tag ?a ?b)
-)
-Then 
-(
-	(Delete (Tag ?a ?b))
-	(Delete (Step Cleanup Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v3.prs b/bad_detection_rules_v3/bad_detection_rules_v3.prs
deleted file mode 100644
index 41bb113df5f3735d182600ff0c8cf612d59ecf8b..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v3.prs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal do detection_task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal do detection_task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
-))
-
-
-(TRIAL_start_trial
-If
-(
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Visual_Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(DETECT_fixation_onset
-If
-(
-	(Step Waitfor Visual_Fixation_Onset)
-	(Visual ?a Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?a)
-	(Add (Tag ?a Fixation_Symbol))
-	(Delete (Step Waitfor Visual_Fixation_Onset))
-	(Add (Step Waitfor Visual_Stim_Onslet))
-))
-
-(DETECT_stimulus_onset
-If
-(
-	(Step Waitfor Visual_Stim_Onset)
-	(Visual ?sobj Detection Onset)
-	(Tag ?fobj Fixation_Symbol)
-	(DIFFERENT ?sobj ?fobj)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stim_Onset))
-	(Add (Step Make Visual_Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_inintiate_visual_response
-If
-(
-	(Step Make Visual_Response)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Visual_Response))
-	(Add (Step Do Cleanup))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(TRIAL_cleanup_trial
-If 
-(
-	(Step Do Cleanup)
-	(Tag ?x ?y)
-)
-Then 
-(
-	(Delete (Tag ?x ?y))
-	(Delete (Step Do Cleanup))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v4.prs b/bad_detection_rules_v3/bad_detection_rules_v4.prs
deleted file mode 100644
index c0e394b57e7cbbcde4d9e79c2025f163aaa57940..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v4.prs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal do detection_task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal do detection_task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
-))
-
-
-(TRIAL_start_trial
-If
-(
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(Trial_fixation_onset
-If
-(
-	(Step Waitfor Fixation_Onset)
-	(Visual ?fixation Detection Onset)	
-	(Motor Ocular Preparation Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?fixation_location)
-	(Add (Tag ?fixation Fixation_Symbol))
-	(Delete (Step Waitfor Fixation_Onset))
-	(Add (Step Waitfor Stim_Onset))
-))
-
-(VISUAL_stimulus_onset
-If
-(
-	(Step Waitfor Stim_Onset)
-	(Visual ?a Detection Onset)
-	(Tag ?b Fixation_Symbol)
-	(DIFFERENT ?a ?b)
-)
-Then
-(
-	(Delete (Step Waitfor Stim_Onset))
-	(Add (Step Make Visual_Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_make_response
-If
-(
-	(Step Make Visual_Response)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Visual_Response))
-	(Add (Step CleanUp Memory))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(TRIAL_cleanup_memory
-If 
-(
-	(Step CleanUp Memory)
-	(Tag ?x ?y)
-)
-Then 
-(
-	(Delete (Tag ?x ?y))
-	(Delete (Step CleanUp Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v5.prs b/bad_detection_rules_v3/bad_detection_rules_v5.prs
deleted file mode 100644
index 73a5a18ea075f44380077402dd0da36191137d85..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v5.prs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal play detection_game))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal play detection_game)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
-))
-
-
-(TRIAL_start_trial
-If
-(
-	(Goal play detection_game)
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Visual_Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(VISUAL_fixation_onset
-If
-(
-	(Step Waitfor Visual_Fixation_Onset)
-	(Visual ?a Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?a)
-	(Add (Tag ?a Fixation_Symbol))
-	(Delete (Step Waitfor Visual_Fixation_Onset))
-	(Add (Step Waitfor Visual_Stimulus_Onset))
-))
-
-(VISUAL_stimulus_onset
-If
-(
-	(Step Waitfor Visual_Stimulus_Onset)
-	(Visual ?x Detection Onset)
-	(Tag ?y Fixation_Symbol)
-	(DIFFERENT ?x ?y)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stimulus_Onset))
-	(Add (Step Make Visual_Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_make_visual_response
-If
-(
-	(Goal play detection_game)
-	(Step Execute Visual_Response)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Visual_Response))
-	(Add (Step Forget LastTrial))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(TRIAL_forget_last_trial
-If 
-(
-	(Step Forget LastTrial)
-	(Tag ?c ?d)
-)
-Then 
-(
-	(Delete (Tag ?c ?d))
-	(Delete (Step Cleanup Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v6.prs b/bad_detection_rules_v3/bad_detection_rules_v6.prs
deleted file mode 100644
index 395066ec9776c81a3468acb84fe7ad6127eeb360..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v6.prs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal do detection_task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal do detection_task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Begin Trial))
-))
-
-
-(TRIAL_start_trial
-If
-(
-	(Step Begin Trial)
- )
-Then
-(
-	(Add (Step Waitfor Visual_Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(VISUAL_fixation_onset
-If
-(
-	(Step Waitfor Visual_Fixation_Onset)
-	(Visual ?z Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?z)
-	(Add (Tag ?z Fixation_Symbol))
-	(Delete (Step Waitfor Visual_Fixation_Onset))
-	(Add (Step Waitfor Visual_Stimulus))
-))
-
-(VISUAL_stimulus_onset
-If
-(
-	(Step Waitfor Visual_Stimulus)
-	(Visual ?bird Detection Onset)
-	(Tag ?lion Fixation_Symbol)
-	(DIFFERENT ?bird ?lion)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stimulus))
-	(Add (Step Start Visual_Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_make_response
-If
-(
-	(Step Start Visual_Response)
-	(Motor Manual Modality Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Start Visual_Response))
-	(Add (Step Cleanup Memory))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(TRIAL_cleanup_trial
-If 
-(
-	(Step Cleanup Memory)
-	(Tag ?g ?h)
-)
-Then 
-(
-	(Delete (Tag ?g ?h))
-	(Delete (Step Cleanup Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v7.prs b/bad_detection_rules_v3/bad_detection_rules_v7.prs
deleted file mode 100644
index 5bbbdbca8e128b46bd832aeb71a902740588ac1d..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v7.prs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal do detection_task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(TRIAL_start_block
-If
-(
-	(Goal do detection_task)
-	(Not (Step ?firefly ?firefly))
- )
-Then
-(
-	(Add (Step Begin Trial))
-))
-
-
-(TRIAL_start_the_trial
-If
-(
-	(Step Begin Trial)
- )
-Then
-(
-	(Delete (Step Begin Trial))
-	(Add (Step Waitfor Fixation_Detection))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(DETECT_THE_FIXATION
-If
-(
-	(Step Waitfor Fixation_Detection)
-	(Visual ?mal Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?mal)
-	(Add (Tag ?mal The Fixation))
-	(Delete (Step Waitfor Fixation_Detection))
-	(Add (Step Waitfor Visual_Stimulus_Onset))
-))
-
-(DETECT_THE_STIMULUS
-If
-(
-	(Step Waitfor Visual_Stimulus_Onset)
-	(Visual ?book Detection Onset)
-	(Tag ?river The Fixation)
-	(DIFFERENT ?book ?river)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stimulus_Onset))
-	(Add (Step Make Response))
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(MANUAL_make_visual_response
-If
-(
-	(Step Make Response)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Response))
-	(Add (Step Cleanup Memory))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(Cleanup_Rule
-If 
-(
-	(Step Cleanup Memory)
-	(Tag ?wash ?zoe)
-)
-Then 
-(
-	(Delete (Tag ?wash ?zoe))
-	(Delete (Step Cleanup Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/bad_detection_rules_v8.prs b/bad_detection_rules_v3/bad_detection_rules_v8.prs
deleted file mode 100644
index 628e876b8acadcead8f9a14e3efb1b140628ea2b..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/bad_detection_rules_v8.prs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Device file: mhpdetection_device3
-
-
-//Setup Initial Working Memory contents. 
-(Define Initial_memory_contents (Goal Do Detection_Task))
-
-
-//**********************************************************************************************
-;#BLOCK_AND_TRIAL_MANAGEMENT_RULES
-//**********************************************************************************************
-
-(Start_Block
-If
-(
-	(Goal Do Detection_Task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
-))
-
-
-(Start_Trial
-If
-(
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Visual_Fixation_Onset))
-))
-
-
-//**********************************************************************************************
-;#VISUAL_PERCEPTION_RULES
-//**********************************************************************************************
-
-(Fixation_Onset
-If
-(
-	(Step Waitfor Visual_Fixation_Onset)
-	(Visual FIxation Detection Onset)	
-	(Motor Ocular Modality Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move Fixation)
-	(Add (Tag Fixation Fixation_Symbol))
-	(Delete (Step Waitfor Visual_Fixation_Onset))
-	(Add (Step Waitfor Visual_Stimulus_Onset))
-))
-
-(Stimulus_Onset
-If
-(
-	(Step Waitfor Visual_Stimulus_Onset)
-	(Visual ?a Detection Onset)
-	(Tag ?b Fixation_Symbol)
-	(DIFFERENT ?a ?b)
-)
-Then
-(
-	(Delete (Step Waitfor Visual_Stimulus_onset))
-	(Add (Step Make Visual_Response)
-))
-
-//**********************************************************************************************
-;#RESPONSE_MAPPING_RULES
-//**********************************************************************************************
-
-(Make_Response
-If
-(
-	(Tag Make Visual_Response)
-	(Motor Manual Preparations Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch J Right Index)
-	(Delete (Step Make Visual_Response))
-	(Add (Step Cleanup Memory))
-))
-
-//**********************************************************************************************
-;#CLEANUP_RULES
-//**********************************************************************************************
-
-(Cleanup_Memory
-If 
-(
-	(Step Cleanup Memory)
-	(Tag ?this ?that)
-)
-Then 
-(
-	(Delete (Tag ?this ?that))
-	(Delete (Step Cleanup Memory))
-))
\ No newline at end of file
diff --git a/bad_detection_rules_v3/prompt.txt b/bad_detection_rules_v3/prompt.txt
deleted file mode 100644
index 3448c480595a6b47cf9ffa1a31beb3a7659c4c0e..0000000000000000000000000000000000000000
--- a/bad_detection_rules_v3/prompt.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-prompt.txt
-
-This folder contains several broken rule files for use with the detection task device.
-
-Fix each rule so that it runs in EPIC with the detection task. 
-
-At the top of each rule file, add a comment that just mentions what you did to fix the rules.
-
-Warnings and Notices: 
-
-Use TextWranger or some other REAL text editor. Mac's TextEdit, MS Word, or any such program will break your rules in a way that you will not be able to detect and fix easily. If you want to use a program on mac or pc to edit rules and are unsure if it will kill your rules, ask me.
-
-DO NOT add any other comments, notes, extra spaces, or extra lines. Your goal is not to make these rules look just like the default ones, just fix them so they run and add your single line comment at the top (don't forget the //). Some variables, steps, and rule names may differ from file to file. They may also differ from your current basic_detection_rules.prs file. These are not errors. They are there to make sure you change only what is REQUIRED to make the rules work. Any changes that are not required will lower your score.
-
-When done, compress (aka zip) all the rules you've edited and upload them Canvas. On mac, you can use the mouse to select all of the files you want to compress, then control click them and you should see a drop down menu with COMPRESS as one of the options. You'll end up with a file with at .zip extension at the end of the filename --> turn that one in.
\ No newline at end of file
diff --git a/devices.zip b/devices.zip
deleted file mode 100644
index 0fa94eec9f01ec6fa95af202262aa6c1cac046ab..0000000000000000000000000000000000000000
Binary files a/devices.zip and /dev/null differ
diff --git a/devices/choice/encoders/donders_visual_encoder.py b/devices/choice/encoders/donders_visual_encoder.py
deleted file mode 100644
index 125fa91babfe09ab448855a87ea31a92214ce4bb..0000000000000000000000000000000000000000
--- a/devices/choice/encoders/donders_visual_encoder.py
+++ /dev/null
@@ -1,81 +0,0 @@
-from typing import Any
-
-from epicpydevice.epicpy_visual_encoder_base import EPICPyVisualEncoder
-from epicpydevice.symbol import Symbol
-from epicpydevice.random_utilities import unit_uniform_random_variable
-from epicpydevice.standard_utility_symbols import Nil_c
-from epicpydevice.standard_symbols import (
-    Text_c,
-    Color_c,
-    Red_c,
-    Green_c,
-    Blue_c,
-    Yellow_c,
-    Shape_c,
-    Circle_c,
-    Filled_Rectangle_c,
-)
-
-
-# EpicPy will expect all visual encoders to be of class
-# VisualEncoder and subclassed from EPICPyVisualEncoder.
-
-
-class VisualEncoder(EPICPyVisualEncoder):
-    def __init__(self, encoder_name: str, parent: Any = None):
-        super(VisualEncoder, self).__init__(
-            encoder_name=encoder_name if encoder_name else "VisualEncoder",
-            parent=parent,
-        )
-        self.recoding_failure_rate = 0.5
-
-    def set_object_property(
-        self,
-        object_name: Symbol,
-        property_name: Symbol,
-        property_value: Symbol,
-        encoding_time: int,
-    ) -> bool:
-        """
-        Imparts a self.recoding_failure_rate chance of mis-perceiving object colors:
-        Yellow->Blue & Green->Red.
-        If not overridden, this method just returns False to indicate that the encoding
-        is not being handled here.
-        """
-
-        # this encoding does not apply
-        if property_name != Color_c:
-            return False
-
-        # failure rate is 0, nothing to do
-        if not self.recoding_failure_rate:
-            return False
-
-        # can only confuse green and yellow
-        if property_value not in (Yellow_c, Green_c, Nil_c):
-            return False
-
-        # flip a coin to decide whether encoding is successful
-        successful_encoding = (
-            unit_uniform_random_variable() > self.recoding_failure_rate
-        )
-
-        if property_value == Nil_c:
-            # previous property values need to be removed!
-            encoding = Nil_c
-        elif property_value == Yellow_c:
-            # random chance of perceiving yellow as blue!
-            encoding = property_value if successful_encoding else Blue_c
-        elif property_value == Green_c:
-            # random chance of perceiving yellow as red!
-            encoding = property_value if successful_encoding else Red_c
-        else:
-            return False  # this encoding does not apply
-
-        # transmit forward the encoded Shape
-        self.schedule_change_property_event(
-            encoding_time, object_name, property_name, encoding
-        )
-
-        # this encoding applied
-        return True
diff --git a/devices/detection/detection_device.py b/devices/detection/detection_device.py
deleted file mode 100644
index 80109f73782316fe6db8fba6cac7c401be90e0fc..0000000000000000000000000000000000000000
--- a/devices/detection/detection_device.py
+++ /dev/null
@@ -1,843 +0,0 @@
-import textwrap
-from typing import Any
-
-from pathlib import Path
-from enum import Enum, auto
-import random
-from datetime import datetime
-
-from epicpydevice import epicpy_device_base
-from epicpydevice.symbol import Symbol
-from epicpydevice.output_tee import Output_tee
-from epicpydevice.epic_statistics import Mean_accumulator
-from epicpydevice.symbol_utilities import concatenate_to_Symbol, get_nth_Symbol
-from epicpydevice.device_exception import Device_exception
-from epicpydevice.speech_word import Speech_word
-import epicpydevice.geometric_utilities as GU
-from epicpydevice.standard_symbols import (
-    Red_c,
-    Green_c,
-    Blue_c,
-    Yellow_c,
-    Black_c,
-    Text_c,
-    Color_c,
-    Shape_c,
-    Circle_c,
-)
-
-import pingouin as pg
-import pandas as pd
-import matplotlib.pyplot as plt
-import seaborn as sns
-from matplotlib.legend_handler import HandlerTuple
-
-
-class state(Enum):
-    START = auto()
-    START_TRIAL = auto()
-    PRESENT_FIXATION = auto()
-    REMOVE_FIXATION = auto()
-    PRESENT_STIMULUS = auto()
-    WAITING_FOR_RESPONSE = auto()
-    DISCARD_STIMULUS = auto()
-    FINISH_TRIAL = auto()
-    SHUTDOWN = auto()
-
-
-USING_OLDER_EPICLIB = False
-
-# EpicPy will expect all devices to be of class "EpicDevice" and subclassed from
-# "EpicPyDevice" or "epicpy_device.EpicPyDevice"
-
-
-class EpicDevice(epicpy_device_base.EpicPyDevice):
-    def __init__(self, ot: Output_tee, parent: Any, device_folder: Path):
-        epicpy_device_base.EpicPyDevice.__init__(
-            self,
-            parent=parent,
-            ot=ot,
-            device_name="Detection_Device_v2025.1",
-            device_folder=device_folder,
-        )
-
-        # NOTE: ot is not being used, just use self.write(...)
-        self.device_name = "Detection_Device_v2022.3"
-        self.condition_string = "10 4 Hard Draft"  # from EpicPyDevice, default is ''
-        self.n_trials = 10
-        self.color_count = 4
-        self.task_difficulty = "Hard"
-        self.tag_str = "Draft"
-
-        # differentiator in case this data is combined with Detection data
-        self.task_name = "Detection"
-
-        self.trial = 0
-        self.run_id = self.unique_id()
-
-        self.current_vrt = Mean_accumulator()
-
-        # EPIC Simulation controller will know device is finished when
-        #   self.state == self.SHUTDOWN
-        self.state = state.START  # from EpicPyDevice, default is 0
-        self.SHUTDOWN = state.SHUTDOWN  # from EPICPyDevice, default is 1000
-
-        self.vresponse_made = False
-        self.vstims = [Red_c, Green_c, Blue_c, Yellow_c]
-        self.vresps = [Symbol("U")] * 4
-        self.vstimresp = list(zip(self.vstims, self.vresps))
-        self.vstim_color = None
-        self.correct_vresp = None
-        self.vstim_name = None
-        self.vstim_xloc = None
-        self.vstim_onset = 0
-
-        self.reparse_conditionstring = False  # from EpicPyDevice, default is False
-
-        # device constants
-        self.Warning_c = Symbol("#")
-        self.VWarn_c = Symbol("Fixation")
-        self.VStim_c = Symbol("Stimulus")
-        self.ColorWord_c = Symbol("ColorWord")
-        self.Center_screen_c = Symbol("Center_screen")
-
-        # experiment constants
-        self.wstim_location_c = GU.Point(0.0, 0.0)
-        self.wstim_size_c = GU.Size(1.0, 1.0)
-        self.vstim_size_c = GU.Size(2.0, 2.0)
-        self.intertrialinterval_c = 5000
-
-        # Optionally expose some boolean device options to the user via the GUI.
-        self.option = dict()  # from EpicPyDevice, default is dict()
-        # useful for showing debug information during development
-        self.option["show_debug_messages"] = True
-        # useful for showing device state info during trial run
-        self.option["show_trial_events"] = True
-        # useful for outputting trial parameters and data during task run
-        self.option["show_trial_data"] = True
-        # useful for long description of the task and parameters
-        self.option["show_task_description"] = True
-        # useful for timing runs
-        self.option["show_task_statistics"] = True
-
-        # a datafile is automatically managed by EpicPyDevice.
-        # Use self.data_writer.writerow(TUPLE OF VALUES) to write each row of csv data.
-        # Need to first define the data header or your csv file could be malformed:
-        self.data_header = (
-            "RunID",
-            "Trial",
-            "Task",
-            "Difficulty",
-            "StimColor",
-            "StimPos",
-            "CorrectResponse",
-            "Response",
-            "Modality",
-            "RT",
-            "Accuracy",
-            "Tag",
-            "Device",
-            "Rules",
-            "Date",
-        )
-
-        # assumes device file is next to folder called images!
-        self.show_view_background(
-            view_type="visual", file_name="donders_monitor.png", scaled=True
-        )
-        self.show_view_background(
-            view_type="auditory", file_name="donders_tones.png", scaled=True
-        )
-
-        if self.option["show_task_description"]:
-            self.describe_task()
-
-    def parse_condition_string(self):
-        error_msg = (
-            f"{self.condition_string}\n Should be: space-delimited "
-            f"trials(int > 0) colors(1-4) difficulty(Easy or Hard) "
-            f"tag(any string)"
-        )
-
-        # returns items from space delimited condition string as strings.
-        # Uses self.get_param_list() instead of self.condition_string.split(' ') to
-        # ensure any accidentally remaining range information is ignored.
-        params = self.get_param_list()
-
-        try:
-            assert len(params) == 4, "Incorrect condition string: "
-            trials, colors, difficulty, tag = params
-            difficulty = difficulty.lower()
-            trials = int(trials) if str(trials).isdigit() else 0
-            colors = int(colors) if str(colors).isdigit() else 0
-            assert trials > 0, "Number of trials must be positive: "
-            assert 1 <= colors <= 4, "Colors must be between 1 and 4"
-            assert difficulty in (
-                "easy",
-                "hard",
-            ), "Task difficulty must be 'Easy' or 'Hard'"
-        except AssertionError as e:
-            raise Device_exception(
-                f"Error Parsing the Condition String: {e} | {error_msg}"
-            )
-
-        self.color_count = colors
-        self.n_trials = trials
-        self.task_difficulty = difficulty
-        self.tag_str = tag
-
-        self.reparse_conditionstring = False
-
-    def initialize(self):
-        """
-        Initializes run. Called whenever model is stopped and started anew.
-        I.e., NOT called, when model is paused and resumed.
-        """
-        self.vresponse_made = False
-        self.trial = 0
-        self.run_id = self.unique_id()
-        self.state = state.START
-        self.current_vrt.reset()
-
-        # from EpicPyDevice, recommended for your initialize method!
-        self.init_data_output()
-
-    def describe_task(self):
-        description = f"""
-        ******************************************************************
-        f"Initializing Device: {self.device_name.replace('_', ' ')} 
-        f"Current Parameter String: {self.condition_string}
-        ******************************************************************
-
-        Events
-        ------
-         - Trial Start
-         - Warning Signal (Simultaneous Visual and Auditory)
-           Visual: "#" (1000 ms)
-           Auditory: 'Beep' for 300 ms & 
-         - Blank Screen (500-1300 ms random)
-         - Stimulus (Simultaneous Visual and Auditory) for 500 ms
-           Visual: Red, Green, Blue, or Yellow filled circle 
-           Auditory: "Ding", "Dong", "Bing", or "Bong"
-         - Waits for keyboard button press or vocal utterance
-           Correct Responses
-           Keyboard: U is always correct
-           Vocal: "U" is always correct
-         - Inter-Trial Interval, Blank Screen, for 5000 ms
-
-        Conditions:
-        ----------
-         - Easy: X position is at screen center (x = 0)
-         - Hard: X position randomly selected from [-2, -1, 0, 1, 2]
-
-        Parameter String:
-        ----------------
-         - Structure: TRIALS NUM_COLORS DIFFICULTY TAG
-         - Values: Trials: Integer > 0 
-                   Num Colors: Integer 1-4
-                   Difficulty: Easy or Hard
-                   Tag: Any Word (simply added to TAG column in data file)
-         - Default: 10 4 Hard Draft
-        ******************************************************************
-        """
-        self.write(textwrap.dedent(description))
-
-    def handle_Start_event(self):
-        """
-        You have to get the ball rolling with a first time-delayed event,
-        nothing happens until you do.
-        """
-        self.schedule_delay_event(500)
-
-    def handle_Stop_event(self):
-        """
-        called after the stop_simulation function (which is part of the base device class)
-        """
-        self.write(f"{self.processor_info()} received Stop_event\n")
-        self.finalize_data_output()  # from EpicPyDevice, recommended
-        self.refresh_experiment()
-
-    def handle_Delay_event(
-        self,
-        _type: Symbol,
-        datum: Symbol,
-        object_name: Symbol,
-        property_name: Symbol,
-        property_value: Symbol,
-    ):
-        global DEVICE_FINISHED
-        if self.state == state.START:
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: START\n")
-            self.state = state.START_TRIAL
-            self.schedule_delay_event(500, Symbol("StartTrial"), Symbol())
-        elif self.state == state.START_TRIAL and _type == Symbol("StartTrial"):
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: START_TRIAL\n")
-            self.vresponse_made = False
-            self.start_trial()
-            self.state = state.PRESENT_FIXATION
-            self.schedule_delay_event(100, Symbol("PresentFixation"), Symbol())
-        elif self.state == state.PRESENT_FIXATION and _type == Symbol(
-            "PresentFixation"
-        ):
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: PRESENT_FIXATION\n")
-            self.present_fixation_point()
-            self.state = state.REMOVE_FIXATION
-            self.schedule_delay_event(1000, Symbol("RemoveFixation"), Symbol())
-        elif self.state == state.REMOVE_FIXATION and _type == Symbol("RemoveFixation"):
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: REMOVE_FIXATION\n")
-            self.remove_fixation_point()
-            self.state = state.PRESENT_STIMULUS
-            stimwaittime = random.randint(800, 1300)
-            self.schedule_delay_event(stimwaittime, Symbol("PresentStimulus"), Symbol())
-        elif self.state == state.PRESENT_STIMULUS:
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: PRESENT_STIMULUS\n")
-            self.present_stimulus()
-            self.state = state.WAITING_FOR_RESPONSE
-            self.schedule_delay_event(100, Symbol("WaitForResp"), Symbol())
-        elif self.state == state.WAITING_FOR_RESPONSE and _type == Symbol(
-            "WaitForResp"
-        ):
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: WAITING_FOR_RESPONSE\n")
-            # nothing to do, just wait
-            # note: next state and schedule_delay_event sent by response handler!
-        elif self.state == state.DISCARD_STIMULUS:
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: DISCARD_STIMULUS\n")
-            self.remove_stimulus()
-            self.state = state.FINISH_TRIAL
-            self.schedule_delay_event(
-                self.intertrialinterval_c, Symbol("FinishTrial"), Symbol()
-            )
-        elif self.state == state.FINISH_TRIAL and _type == Symbol("FinishTrial"):
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: FINISH_TRIAL\n")
-            self.setup_next_trial()
-        elif self.state == state.SHUTDOWN:
-            if self.option["show_trial_events"]:
-                self.write("********-->STATE: SHUTDOWN\n")
-            self.stop_simulation()  # doesn't do anything in EpicPy...could just omit
-        else:
-            raise Device_exception(
-                f"Device delay event in unknown or improper device state: {self.state}"
-            )
-
-    def start_trial(self):
-        if self.option["show_debug_messages"]:
-            self.write("*trial_start|")
-
-        if self.reparse_conditionstring:
-            self.parse_condition_string()
-            self.initialize()
-
-        self.trial += 1
-
-        if self.option["show_debug_messages"]:
-            self.write("trial_start*\n")
-
-    def present_fixation_point(self):
-        if self.option["show_debug_messages"]:
-            self.write("*present_fixation|")
-
-        self.wstim_v_name = concatenate_to_Symbol(self.VWarn_c, self.trial)
-        self.make_visual_object_appear(
-            self.wstim_v_name, self.wstim_location_c, self.wstim_size_c
-        )
-        self.set_visual_object_property(self.wstim_v_name, Text_c, self.Warning_c)
-        self.set_visual_object_property(self.wstim_v_name, Color_c, Black_c)
-
-        # no need to keep ref, sound will remove itself after a delay
-        wstim_snd_name = concatenate_to_Symbol("WarningSound", self.trial)
-        self.make_auditory_sound_event(
-            wstim_snd_name, Symbol("Signal"), GU.Point(0, -5), Symbol("Beep"), 12, 300
-        )
-
-        wstim_snd_name = Symbol(f"WarningSpeech{self.trial}")
-
-        warning_word = Speech_word(
-            name=wstim_snd_name,
-            stream_name=Symbol("ComputerSpeaker"),
-            time_stamp=self.get_time(),
-            location=GU.Point(0, -10),
-            pitch=16.0,
-            loudness=13.0,
-            duration=500.0,
-            level_left=1.0,
-            level_right=1.0,
-            content=Symbol("Warning"),
-            speaker_gender=Symbol("Any"),
-            speaker_id=Symbol("Computer"),
-            utterance_id=100,
-        )
-
-        self.make_auditory_speech_event(warning_word)
-
-        if self.option["show_debug_messages"]:
-            self.write("present_fixation*\n")
-
-    def remove_fixation_point(self):
-        if self.option["show_debug_messages"]:
-            self.write("*remove_fixation|")
-
-        self.make_visual_object_disappear(self.wstim_v_name)
-
-        if self.option["show_debug_messages"]:
-            self.write("remove_fixation*\n")
-
-    def present_stimulus(self):
-        if self.option["show_debug_messages"]:
-            self.write("*present_stimulus|")
-
-        self.vstim_color, self.correct_vresp = random.choice(self.vstimresp)
-        self.vstim_name = concatenate_to_Symbol(self.VStim_c, self.trial)
-
-        if self.task_difficulty == "easy":
-            self.vstim_xloc = 0.0
-        else:
-            self.vstim_xloc = random.choice((-2.0, -1.0, 0.0, 1.0, 2.0))
-
-        self.make_visual_object_appear(
-            self.vstim_name, GU.Point(self.vstim_xloc, 0.0), self.vstim_size_c
-        )
-        self.set_visual_object_property(self.vstim_name, Shape_c, Circle_c)
-        self.set_visual_object_property(self.vstim_name, Color_c, self.vstim_color)
-
-        self.vstim_onset = self.get_time()
-        self.vresponse_made = False
-
-        # no need to keep ref, sound will remove itself after a delay
-        vstim_snd_name = concatenate_to_Symbol("StimulusSound", self.trial)
-        stim_sound = {"Red": "Ding", "Green": "Dong", "Blue": "Bing", "Yellow": "Bong"}
-
-        self.make_auditory_sound_event(
-            vstim_snd_name,
-            Symbol("Signal"),
-            GU.Point(0, 10),
-            Symbol(stim_sound[str(self.vstim_color)]),
-            12,
-            500,
-            500,
-        )
-
-        if self.option["show_debug_messages"]:
-            self.write("present_stimulus*\n")
-
-    def remove_stimulus(self):
-        if self.option["show_debug_messages"]:
-            self.write("*remove_stimulus|")
-
-        self.make_visual_object_disappear(self.vstim_name)
-
-        if self.option["show_debug_messages"]:
-            self.write("remove_stimulus*\n")
-
-    def setup_next_trial(self):
-        if self.trial < self.n_trials:
-            if self.option["show_debug_messages"]:
-                self.write("*setup_next_trial|")
-            self.state = state.START_TRIAL
-            self.schedule_delay_event(300, Symbol("StartTrial"), Symbol())
-            if self.option["show_debug_messages"]:
-                self.write("setup_next_trial*\n")
-        else:
-            if self.option["show_debug_messages"]:
-                self.write("*shutdown_experiment|")
-            # things to do prior to shutdown
-            self.finalize_data_output()  # from EpicPyDevice, recommended when task ends!
-            self.show_output_stats()
-            self.refresh_experiment()  # tidy up for subsequent runs
-
-            # shutting down!
-            self.state = self.SHUTDOWN
-            self.schedule_delay_event(500)
-
-            if self.option["show_debug_messages"]:
-                self.write("shutdown_experiment*\n")
-
-    def refresh_experiment(self):
-        self.vresponse_made = False
-        self.trial = 0
-        self.state = state.START
-        self.current_vrt.reset()
-
-    def output_statistics(self):
-        s = (
-            f"Task Name: {self.task_name}  Task Difficulty: {self.task_difficulty}"
-            f"  Trials Run: {self.trials}/{self.n_trials}\n"
-        )
-        self.write(s)
-
-        s = f"N = {self.current_vrt.get_n()}, Mean RT = {self.current_vrt.get_mean()}"
-        self.write(f"{s}\n(note: Mean excludes 1st trial)\n\n")
-
-    def handle_Keystroke_event(self, key_name: Symbol):
-        if self.vresponse_made:
-            return
-
-        if self.option["show_debug_messages"]:
-            self.write("\n*handle_keystroke_event...\n")
-
-        rt = self.get_time() - self.vstim_onset
-        if key_name == self.correct_vresp:
-            outcome = "CORRECT"
-            if self.trial > 1:
-                self.current_vrt.update(rt)
-        else:
-            outcome = "INCORRECT"
-
-        if self.option["show_trial_data"]:
-            # data display for normal output window
-            s = (
-                f"\nTrial: {self.trial} | Task: {self.task_name} | Difficulty: "
-                f"{self.task_difficulty} | RT: {rt} | StimColor: {self.vstim_color} | "
-                f"StimPos: {self.vstim_xloc} | Modality: Keyboard | "
-                f"Response: {key_name} | CorrectResponse: {self.correct_vresp} | "
-                f"Accuracy: {outcome}\n"
-            )
-
-            self.write(s)
-
-        # real data saved to file
-        if self.data_file:
-            # note: order of values dictated by names in self.data_header
-            data = (
-                self.run_id,
-                self.trial,
-                self.task_name,
-                self.task_difficulty,
-                self.vstim_color,
-                self.vstim_xloc,
-                self.correct_vresp,
-                key_name,
-                "Keyboard",
-                rt,
-                outcome,
-                self.tag_str,
-                self.device_name,
-                self.rule_filename,
-                datetime.now().ctime(),
-            )
-            self.data_writer.writerow(data)
-
-        self.vresponse_made = True
-
-        if self.option["show_debug_messages"]:
-            self.write("\nhandle_keystroke_event*\n")
-
-        self.state = state.DISCARD_STIMULUS
-        self.schedule_delay_event(500)
-
-    def handle_Vocal_event(self, vocal_input: Symbol, duration: int = 0):
-        if self.vresponse_made:
-            return
-
-        if self.option["show_debug_messages"]:
-            self.write("\n*handle_vocal_event...\n")
-
-        rt = self.get_time() - self.vstim_onset
-        if vocal_input == self.correct_vresp:
-            outcome = "CORRECT"
-            if self.trial > 1:
-                self.current_vrt.update(rt)
-        else:
-            outcome = "INCORRECT"
-
-        if self.option["show_trial_data"]:
-            # data display for normal output window
-            s = (
-                f"\nTrial: {self.trial} | Task: {self.task_name} | "
-                f"Difficulty: {self.task_difficulty} | "
-                f"RT: {rt} | StimColor: {self.vstim_color} | "
-                f"StimPos: {self.vstim_xloc} | Modality: Vocal | "
-                f"Response: {vocal_input} | CorrectResponse: {self.correct_vresp} | "
-                f"Accuracy: {outcome}\n"
-            )
-
-            self.write(s)
-
-        # real data saved to file
-        if self.data_file:
-            # note: order of values dictated by names in self.data_header
-            data = (
-                self.run_id,
-                self.trial,
-                self.task_name,
-                self.task_difficulty,
-                self.vstim_color,
-                self.vstim_xloc,
-                self.correct_vresp,
-                vocal_input,
-                "Voice",
-                rt,
-                outcome,
-                self.tag_str,
-                self.device_name,
-                Path(self.rule_filename).name,
-                datetime.now().ctime(),
-            )
-            self.data_writer.writerow(data)
-
-        self.vresponse_made = True
-
-        if self.option["show_debug_messages"]:
-            self.write("\nhandle_vocal_event*\n")
-
-        self.state = state.DISCARD_STIMULUS
-        self.schedule_delay_event(500)
-
-    def handle_Eyemovement_Start_event(
-        self, target_name: Symbol, new_location: GU.Point
-    ):
-        ...
-
-    def handle_Eyemovement_End_event(self, target_name: Symbol, new_location: GU.Point):
-        ...
-
-    def show_output_stats(self):
-        # use pandas to load in data run so far (include all data from previous runs)
-        # (assumes self.finalize_data_output() has been called)
-        pd.set_option("display.precision", 3)
-        data = pd.read_csv(self.data_filepath)
-
-        # self.stats_write(f'Outcomes: {set(data.Accuracy)}')
-        correct_data = data.query('Accuracy=="CORRECT"')
-        correct_trials_N = len(correct_data.Accuracy)
-        all_trials_N = len(data.Accuracy)
-        mean_rt = correct_data.RT.mean() if correct_trials_N else None
-        accuracy = ((correct_trials_N / all_trials_N) * 100) if all_trials_N else 0
-        self.stats_write(
-            f"N={all_trials_N}, "
-            f"CORRECT={correct_trials_N} "
-            f"INCORRECT={all_trials_N-correct_trials_N} "
-            f'MEAN_RT={"NA" if mean_rt is None else int(mean_rt)} '
-            f"ACCURACY={accuracy:0.2f}%"
-        )
-
-        if not self.option["show_task_statistics"]:
-            return
-
-        # note: show_output_stats_????() strips incorrect trials from local var data
-        if "Difficulty" in data.columns and sorted(set(data["Difficulty"])) == [
-            "easy",
-            "hard",
-        ]:
-            self.show_output_stats_2way(data)
-        else:
-            self.show_output_stats_1way(data)
-
-    def show_output_stats_1way(self, data: pd.DataFrame):
-        try:
-            data.query('Accuracy=="CORRECT"', inplace=True)
-
-            colors = [str(vstim)[0] for vstim in self.vstims]
-            colors = colors[: self.color_count]
-
-            cond = str(data["Difficulty"][0]).title()
-
-            self.stats_write(
-                f"<h4>Choice Task<br>ANOVA: RT by StimColor<br>{colors}<br>{cond} "
-                f"Condition.</h4>",
-                color="Orange",
-            )
-
-            # display table
-            try:
-                table = data.groupby(["StimColor"])["RT"].agg(["mean", "count"])
-                table = table.astype(int)
-                self.stats_write(table.transpose())
-            except Exception as e:
-                self.stats_write(
-                    f"Not enough data to create means table: {e}", color="Red"
-                )
-
-            # display anova results
-            try:
-                err_msg = "Data must contain StimColor with at least 2 colors."
-                assert len(set(data.StimColor)) >= 2, err_msg
-                err_msg = (
-                    "For an ANOVA, the data must contain at least 3 RunIDs "
-                    "from at least 3 separate runs."
-                )
-                assert len(set(data.RunID)) >= 3, err_msg
-
-                aov = pg.rm_anova(data, dv="RT", subject="RunID", within="StimColor")
-
-                # this is cosmetic for demo devices -- helps anova fit in smaller window
-                for factor in ("p-GG-corr", "eps", "sphericity", "W-spher", "p-spher"):
-                    if factor in aov.columns:
-                        aov.drop([factor], axis=1, inplace=True)
-
-                self.stats_write(aov)
-            except AssertionError as e:
-                self.stats_write(
-                    f"Not enough data to run mixed-model anova: {e}", color="Red"
-                )
-            except Exception as e:
-                self.stats_write(f"Unable to run mixed-model anova: {e}", color="Red")
-
-            # create nice bar plot
-            fig, ax = plt.subplots(figsize=(7, 4), dpi=96)
-            sns.set(style="whitegrid", color_codes=True)
-            sns.set_context("paper", font_scale=1.5)  # paper, notebook, talk, poster
-            colors = [
-                "#FFFF00",
-                "#0000FF",
-                "#FF0000",
-                "#00FF00",
-                # "#7F0000",
-                # "#004000",
-                # "#00007F",
-                # "#7F7F00",
-            ]
-            sns.set_palette(sns.color_palette(colors))
-            my_plot = sns.barplot(
-                x="StimColor",
-                hue="StimColor",
-                y="RT",
-                data=data,
-                capsize=0.1,
-                ax=ax,
-                order=["Red", "Green", "Blue", "Yellow"],
-                legend=False
-            )
-
-            highest_mean = int(max(data.groupby(["StimColor"]).RT.mean()) + 50)
-
-            my_plot.set_ylim(150, highest_mean)
-            ticks = list(range(150, highest_mean + 1, 50))
-            my_plot.set_yticks(ticks)
-
-            my_plot.set_yticklabels(ticks)
-
-            my_plot.set_yticks(ticks)
-            my_plot.set_yticklabels(ticks)
-            plt.title(f"Mean RT by Stimulus Color, {cond} Condition")
-            plt.xlabel("Stimulus Color")
-            plt.ylabel("Mean Response Time (ms)")
-            # fig.savefig(f'choice_{cond}_rt_by_stimcolor.png')
-
-            self.stats_write(my_plot.get_figure())
-
-            # cleanup figures so they can be garbage collected before next run
-            plt.close("all")
-
-        except Exception as e:
-            self.stats_write(f"Error showing output stats: {e}", color="Red")
-
-    def show_output_stats_2way(self, data: pd.DataFrame):
-        try:
-            data.query('Accuracy=="CORRECT"', inplace=True)
-
-            colors = [str(vstim)[0] for vstim in self.vstims]
-            colors = colors[: self.color_count]
-
-            self.stats_write(
-                f"<h4>Choice Task<br>ANOVA Difficulty [Hard, Easy] X StimColor "
-                f"{colors}</h4>",
-                color="Orange",
-            )
-
-            # display table
-            try:
-                table = data.groupby(["Difficulty", "StimColor"])["RT"].agg(
-                    ["mean", "count"]
-                )
-                table = table.astype(int)
-                self.stats_write(table.transpose())
-            except Exception as e:
-                self.stats_write(
-                    f"Not enough data to create means table: {e}", color="Red"
-                )
-
-            # display anova results
-            try:
-                err_msg = "Data must contain both 'Hard' and 'Easy' Difficulty."
-                assert len(set(data.Difficulty)) == 2, err_msg
-                err_msg = "Data must contain StimColor with at least 2 colors."
-                assert len(set(data.StimColor)) >= 2, err_msg
-                err_msg = (
-                    "Data must contain at least 4 RunIDs from at least 2 "
-                    "separate runs of 'Easy' Difficulty, and at least 2 separate"
-                    " runs of 'Hard' Difficulty."
-                )
-                assert len(set(data.RunID)) >= 4, err_msg
-
-                aov = pg.mixed_anova(
-                    data,
-                    dv="RT",
-                    subject="RunID",
-                    between="Difficulty",
-                    within="StimColor",
-                )
-
-                # this is cosmetic for demo devices -- helps anova fit in smaller window
-                for factor in ("p-GG-corr", "eps", "sphericity", "W-spher", "p-spher"):
-                    if factor in aov.columns:
-                        aov.drop([factor], axis=1, inplace=True)
-
-                self.stats_write(aov)
-            except AssertionError as e:
-                self.stats_write(
-                    f"Not enough data to run mixed-model anova: {e}", color="Red"
-                )
-            except Exception as e:
-                self.stats_write(f"Unable to run mixed-model anova: {e}", color="Red")
-
-            # create nice bar plot
-            # note: this is more vebose than most figures, but I had to do lots of
-            #       extra stuff to get different palettes for the 2 rows of bars.
-            sns.set(style="whitegrid", color_codes=True)
-            sns.set_context("notebook", font_scale=1.5)  # paper, notebook, talk, poster
-            fig, ax = plt.subplots(figsize=(7, 5), dpi=96)
-            my_plot = sns.barplot(
-                x="StimColor",
-                y="RT",
-                hue="Difficulty",
-                hue_order=("hard", "easy"),
-                palette={"easy": "grey", "hard": "black"},
-                data=data,
-                capsize=0.1,
-                ax=ax,
-            )
-            for bar_group, desaturate_value in zip(ax.containers, (0.4, 1)):
-                for bar, color in zip(
-                    bar_group, ("crimson", "limegreen", "dodgerblue", "yellow")
-                ):
-                    bar.set_facecolor(sns.desaturate(color, desaturate_value))
-
-            ax.legend(
-                handles=[tuple(bar_group) for bar_group in ax.containers],
-                labels=[bar_group.get_label() for bar_group in ax.containers],
-                title=ax.legend_.get_title().get_text(),
-                handlelength=4,
-                handler_map={tuple: HandlerTuple(ndivide=None, pad=0.1)},
-            )
-
-            plt.title("Mean RT by Difficulty and Stimulus Color")
-            plt.xlabel("Stimulus Color")
-            plt.ylabel("Mean Response Time (ms)")
-            sns.despine()
-            plt.tight_layout()
-
-            self.stats_write(my_plot.get_figure())
-
-            # cleanup figures so they can be garbage collected before next run
-            plt.close("all")
-
-        except Exception as e:
-            self.stats_write(f"Error showing output stats: {e}", color="Red")
-
-    def __getattr__(self, name):
-        def _missing(*args, **kwargs):
-            print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
-            print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
-            print("A missing method was called.")
-            print(f"The object was {self}, the method was {name}. ")
-            print(f"It was called with {args} and {kwargs} as arguments\n")
-
-        return _missing
diff --git a/devices/detection/encoders/donders_auditory_encoder.py b/devices/detection/encoders/donders_auditory_encoder.py
deleted file mode 100644
index 13243d19caa059432409f52e3fc92af478dd6c6e..0000000000000000000000000000000000000000
--- a/devices/detection/encoders/donders_auditory_encoder.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from epicpydevice.epicpy_auditory_encoder_base import EPICPyAuditoryEncoder
-import epicpydevice.geometric_utilities as GU
-from epicpydevice.random_utilities import unit_uniform_random_variable
-
-# EpicPy will expect all auditory encoders to be of class
-# AuditoryEncoder and subclassed from EPICPyAuditoryEncoder.
-
-
-class AuditoryEncoder(EPICPyAuditoryEncoder):
-    def __init__(self, encoder_name: str, parent):
-        super(AuditoryEncoder, self).__init__(
-            encoder_name=encoder_name if encoder_name else "AuditoryEncoder",
-            parent=parent,
-        )
-
-        self.recoding_failure_rate = 0.5
-
-    def recode_location(self, original_location: GU.Point) -> GU.Point:
-        """
-        Imparts a self.recoding_failure_rate of mis-perceiving the y location
-        of an auditory stimulus. If not overridden, default will return original_location
-        """
-
-        x, y = original_location.x, original_location.y
-
-        # Currently, in the choice and detection devices, all auditory stimuli are
-        # either at (-5, 5) or (5, 5) let's have a self.recoding_failure_rate
-        # chance of perceiving the y location as 0
-
-        # flip a coin to decide whether encoding is successful
-        successful_encoding = (
-            unit_uniform_random_variable() > self.recoding_failure_rate
-        )
-
-        y = y if successful_encoding else 0
-
-        return GU.Point(x, y)
diff --git a/devices/detection/images/donders_monitor.png b/devices/detection/images/donders_monitor.png
deleted file mode 100644
index ae95f368d6c98d7a2ab7c7b56084a26bda7277ce..0000000000000000000000000000000000000000
Binary files a/devices/detection/images/donders_monitor.png and /dev/null differ
diff --git a/devices/detection/images/donders_tones.png b/devices/detection/images/donders_tones.png
deleted file mode 100644
index 65d5f76bf00cfc3f0bb8257294ba108a9dce404d..0000000000000000000000000000000000000000
Binary files a/devices/detection/images/donders_tones.png and /dev/null differ
diff --git a/devices/detection/rules/detection_rules_AV.prs b/devices/detection/rules/detection_rules_AV.prs
deleted file mode 100644
index 9ddab9f04542bb00f9c505da620c3e9c4d2da489..0000000000000000000000000000000000000000
--- a/devices/detection/rules/detection_rules_AV.prs
+++ /dev/null
@@ -1,114 +0,0 @@
-// Detection Task Rules Auditory-Vocal Version
-// detection_device.py
-
-//Setup Initial WM contents.
-(Define Initial_memory_contents (Goal Do detection_task))
-
-(Define Parameters
-	//(Visual_perceptual_processor Recoding_failure_rate1 Fixed 0.5)
-	//(Auditory_perceptual_processor Recoding_failure_rate1 Fixed 0.5)
-	(Manual Execution_fluctuation_factor Normal When_used 1.0 0.1)
-	(Eye Eccentricity_fluctuation_factor Normal When_used 1.0 0.1)
-	(Eye Property_delay_fluctuation_factor Normal When_used 1.0 0.1)
-)
-
-(Define Named_location Center_screen 0.0 0.0)
-
-//**********************************************************************************************
-//             BLOCK AND TRIAL MANAGEMENT RULES
-//**********************************************************************************************
-
-(TRIAL_mfg
-If
-(
-	(Goal Do detection_task)
-	(Not (Step ??? ???))     ;wildcards
- )
-Then
-(
-	(Add (Step Start Trial))
- )
-)
-
-
-(TRIAL_start_trial
-If
-(
-	(Goal Do detection_task)
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Auditory_Fixation_Onset))
- )
-)
-
-
-(TRIAL_cleanup
-If (
-	(Goal Do detection_task)
-	(Step Cleanup Memory)
-	(Tag ?x ?y)
-)
-Then (
-	(Delete (Tag ?x ?y))
-	(Delete (Step Cleanup Memory))
-))
-
-
-//**********************************************************************************************
-//              MAIN RULESET
-//**********************************************************************************************
-
-(AUD_Auditory_warning_onset
-If
-(
-	(Goal Do detection_task)
-	(Step Waitfor Auditory_Fixation_Onset)
-	(Auditory ?x Detection Onset)
-	(Auditory ?x Stream Signal)
-)
-Then
-(
-	(Add (Tag ?x Fixation_Sound))
-	(Delete (Step Waitfor Auditory_Fixation_Onset))
-	(Add (Step Waitfor Auditory_Stimulus_Onset))
-))
-
-(AUD_Auditory_stimulus_onset
-If
-(
-	(Goal Do detection_task)
-	(Step Waitfor Auditory_Stimulus_Onset)
-	(Auditory ?x Detection Onset)
-	(Auditory ?x Stream Signal)
-	(Tag ?y Fixation_Sound)
-	(DIFFERENT ?x ?y)
-)
-Then
-(
-	(Add (Tag ?x Auditory_Stimulus))
-	(Delete (Step Waitfor Auditory_Stimulus_Onset))
-	(Add (Step Make Manual_Response))
-))
-
-//**********************************************************************************************
-//              RESPONSE RULES
-//**********************************************************************************************
-
-
-(MAN_make_Manual_response
-If
-(
-	(Goal Do detection_task)
-	(Step Make Manual_Response)
-	(Tag ??? Auditory_Stimulus)
-	(Motor Vocal Preparation Free)
-)
-Then
-(
-	(Send_to_motor Vocal Perform Speak U)
-	(Delete (Step Make Manual_Response))
-	(Add (Step Cleanup Memory))
-))
diff --git a/devices/detection/rules/detection_rules_VM.prs b/devices/detection/rules/detection_rules_VM.prs
deleted file mode 100644
index 4ee8b24c9555843e17e0565dca5461bb79b5a228..0000000000000000000000000000000000000000
--- a/devices/detection/rules/detection_rules_VM.prs
+++ /dev/null
@@ -1,116 +0,0 @@
-// Detection Task Rules Visual-Manual Version
-// detection_device.py
-
-//Setup Initial WM contents.
-(Define Initial_memory_contents (Goal Do detection_task))
-
-(Define Parameters
-	//(Visual_perceptual_processor Recoding_failure_rate1 Fixed 0.5)
-	//(Auditory_perceptual_processor Recoding_failure_rate1 Fixed 0.5)
-	(Manual Execution_fluctuation_factor Normal When_used 1.0 0.1)
-	(Eye Eccentricity_fluctuation_factor Normal When_used 1.0 0.1)
-	(Eye Property_delay_fluctuation_factor Normal When_used 1.0 0.1)
-)
-
-(Define Named_location Center_screen 0.0 0.0)
-
-//**********************************************************************************************
-//             BLOCK AND TRIAL MANAGEMENT RULES
-//**********************************************************************************************
-
-(TRIAL_mfg
-If
-(
-	(Goal Do detection_task)
-	(Not (Step ??? ???))
- )
-Then
-(
-	(Add (Step Start Trial))
- )
-)
-
-
-(TRIAL_start_trial
-If
-(
-	(Goal Do detection_task)
-	(Step Start Trial)
- )
-Then
-(
-	(Delete (Step Start Trial))
-	(Add (Step Waitfor Visual_Fixation_Onset))
- )
-)
-
-
-(TRIAL_cleanup
-If (
-	(Goal Do detection_task)
-	(Step Cleanup Memory)
-	(Tag ?x ?y)
-)
-Then (
-	(Delete (Tag ?x ?y))
-	(Delete (Step Cleanup Memory))
-))
-
-
-//**********************************************************************************************
-//              MAIN RULESET
-//**********************************************************************************************
-
-(VIS_visual_Fixation_onset
-If
-(
-	(Goal Do detection_task)
-	(Step Waitfor Visual_Fixation_Onset)
-	(Visual ?fixation Detection Onset)	
-	(Motor Ocular Processor Free)
-)
-Then
-(
-	(Send_to_motor Ocular Perform Move ?fixation)
-	(Add (Tag ?fixation Fixation_Symbol))
-	(Delete (Step Waitfor Visual_Fixation_Onset))
-	(Add (Step Waitfor Visual_Stimulus_Onset))
-))
-
-(VIS_visual_stimulus_onset
-If
-(
-	(Goal Do detection_task)
-	(Step Waitfor Visual_Stimulus_Onset)
-	(Visual ?visualstimulus Detection Onset)
-	(Tag ?fixation Fixation_Symbol)
-	(DIFFERENT ?visualstimulus ?fixation)
-)
-Then
-(
-	(Add (Tag ?visualstimulus Visual_Stimulus)) 
-	(Delete (Step Waitfor Visual_Stimulus_Onset))
-	(Add (Step Make Visual_Response))
-))
-
-//**********************************************************************************************
-//              RESPONSE RULES
-//**********************************************************************************************
-
-
-
-(MAN_make_visualresponse
-If
-(
-	(Goal Do detection_task)
-	(Step Make Visual_Response)
-	(Tag ??? Visual_Stimulus)
-	(Motor Manual Preparation Free)
-)
-Then
-(
-	(Send_to_motor Manual Perform Punch U Right Index)
-	(Delete (Step Make Visual_Response))
-	(Add (Step Cleanup Memory))
-))
-
diff --git a/devices/choice/__init__.py b/devices/devices/__init__.py
similarity index 100%
rename from devices/choice/__init__.py
rename to devices/devices/__init__.py
diff --git a/devices/choice/encoders/__init__.py b/devices/devices/choice/__init__.py
similarity index 100%
rename from devices/choice/encoders/__init__.py
rename to devices/devices/choice/__init__.py
diff --git a/devices/choice/choice_device.py b/devices/devices/choice/choice_device.py
similarity index 83%
rename from devices/choice/choice_device.py
rename to devices/devices/choice/choice_device.py
index 413041f154ced6474a776582853b0d33c6474dd3..adb9f26c3045b7516df9268abd61eda491d6f2c1 100644
--- a/devices/choice/choice_device.py
+++ b/devices/devices/choice/choice_device.py
@@ -31,7 +31,11 @@ import pandas as pd
 import matplotlib.pyplot as plt
 import seaborn as sns
 from matplotlib.legend_handler import HandlerTuple
+import warnings
 
+warnings.filterwarnings("ignore", module="matplotlib\..*")
+warnings.filterwarnings("ignore", module="pingouin\..*")
+warnings.filterwarnings("ignore", module="pandas\..*")
 
 class state(Enum):
     START = auto()
@@ -57,12 +61,12 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
             self,
             parent=parent,
             ot=ot,
-            device_name="Choice_Device_v2025.1",
+            device_name="Choice_Device_v2025.3.19",
             device_folder=device_folder,
         )
 
         # NOTE: ot is not being used, just use self.write(...)
-        self.device_name = "Choice_Device_v2022.3"
+        # self.device_name = "Choice_Device_v2025.3.19"
         self.condition_string = "10 4 Hard Draft"  # from EpicPyDevice, default is ''
         self.n_trials = 10
         self.color_count = 4
@@ -141,13 +145,13 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
             "Date",
         )
 
-        # assumes device file is next to folder called images!
-        self.show_view_background(
-            view_type="visual", file_name="donders_monitor.png", scaled=True
-        )
-        self.show_view_background(
-            view_type="auditory", file_name="donders_tones.png", scaled=True
-        )
+        # # assumes device file is next to folder called images!
+        # self.show_view_background(
+        #     view_type="visual", file_name="donders_monitor.png", scaled=True
+        # )
+        # self.show_view_background(
+        #     view_type="auditory", file_name="donders_tones.png", scaled=True
+        # )
 
         if self.option["show_task_description"]:
             self.describe_task()
@@ -690,20 +694,17 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
                 self.stats_write(f"Unable to run mixed-model anova: {e}", color="Red")
 
             # create nice bar plot
+
+            color_map = {
+                "Red": "red",
+                "Green": "green",
+                "Blue": "blue",
+                "Yellow": "yellow"
+            }
+
             fig, ax = plt.subplots(figsize=(7, 4), dpi=96)
             sns.set(style="whitegrid", color_codes=True)
             sns.set_context("paper", font_scale=1.5)  # paper, notebook, talk, poster
-            colors = [
-                "#FFFF00",
-                "#0000FF",
-                "#FF0000",
-                "#00FF00",
-                # "#7F0000",
-                # "#004000",
-                # "#00007F",
-                # "#7F7F00",
-            ]
-            sns.set_palette(sns.color_palette(colors))
             my_plot = sns.barplot(
                 x="StimColor",
                 hue="StimColor",
@@ -712,11 +713,10 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
                 capsize=0.1,
                 ax=ax,
                 order=["Red", "Green", "Blue", "Yellow"],
-                legend=False
+                palette=color_map,
             )
 
-            highest_mean = int(max(data.groupby(["StimColor"]).RT.mean()) + 50)
-
+            highest_mean = int(max(data.groupby(["StimColor"]).RT.mean()) + 100)
             my_plot.set_ylim(150, highest_mean)
             ticks = list(range(150, highest_mean + 1, 50))
             my_plot.set_yticks(ticks)
@@ -725,6 +725,10 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
 
             my_plot.set_yticks(ticks)
             my_plot.set_yticklabels(ticks)
+
+            if ax.legend_ is not None:
+                ax.legend_.remove()
+
             plt.title(f"Mean RT by Stimulus Color, {cond} Condition")
             plt.xlabel("Stimulus Color")
             plt.ylabel("Mean Response Time (ms)")
@@ -735,123 +739,6 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
 
             self.stats_write(my_plot.get_figure())
 
-            # --------------------------------------------------------------------------
-            # ** OPTIONAL GRAPH
-            # --------------------------------------------------------------------------
-            student_data_path = Path(self.data_filepath.parent, 'student_data.csv')
-            if student_data_path.is_file():
-                try:
-                    student_data = pd.read_csv(student_data_path)
-                    combined = pd.concat([data,student_data])
-
-                    # create nice bar plot
-                    fig, ax = plt.subplots(figsize=(7, 4), dpi=96)
-                    sns.set(style="whitegrid", color_codes=True)
-                    sns.set_context("paper", font_scale=1.5)  # paper, notebook, talk, poster
-                    my_plot = sns.barplot(
-                        x="StimColor",
-                        hue="Rules",
-                        y="RT",
-                        data=combined,
-                        capsize=0.1,
-                        ax=ax,
-                        order=["Red", "Green", "Blue", "Yellow"],
-                        legend=True
-                    )
-
-                    highest_mean = int(max(combined.groupby(["StimColor", "Rules"]).RT.mean()) + 50)
-
-                    my_plot.set_ylim(150, highest_mean)
-                    ticks = list(range(150, highest_mean + 1, 50))
-                    my_plot.set_yticks(ticks)
-
-                    my_plot.set_yticklabels(ticks)
-
-                    my_plot.set_yticks(ticks)
-                    my_plot.set_yticklabels(ticks)
-                    plt.title(f"Mean RT by Stimulus Color Hard (Student Data)")
-                    plt.xlabel("Stimulus Color")
-                    plt.ylabel("Mean Response Time (ms)")
-
-                    plt.tight_layout()
-
-                    self.stats_write(my_plot.get_figure())
-                except Exception as e:
-                    self.stats_write(
-                        f'<br><font color="Red">Error while trying to create student comparison graph: {e}</font><br>'
-                    )
-
-            # --------------------------------------------------------------------------
-
-            # --------------------------------------------------------------------------
-            # ** OPTIONAL GRAPH
-            # --------------------------------------------------------------------------
-            class_data_path = Path(self.data_filepath.parent, 'class_data.csv')
-            if class_data_path.is_file():
-                try:
-                    class_data = pd.read_csv(class_data_path)
-                    combined = pd.concat([data,class_data])
-
-                    # create nice bar plot
-                    fig, ax = plt.subplots(figsize=(7, 4), dpi=96)
-                    sns.set(style="whitegrid", color_codes=True)
-                    sns.set_context("paper", font_scale=1.5)  # paper, notebook, talk, poster
-                    my_plot = sns.barplot(
-                        x="StimColor",
-                        hue="Rules",
-                        y="RT",
-                        data=combined,
-                        capsize=0.1,
-                        ax=ax,
-                        order=["Red", "Green", "Blue", "Yellow"],
-                        legend=True
-                    )
-
-                    highest_mean = int(max(combined.groupby(["StimColor", "Rules"]).RT.mean()) + 50)
-
-                    my_plot.set_ylim(150, highest_mean)
-                    ticks = list(range(150, highest_mean + 1, 50))
-                    my_plot.set_yticks(ticks)
-
-                    my_plot.set_yticklabels(ticks)
-
-                    my_plot.set_yticks(ticks)
-                    my_plot.set_yticklabels(ticks)
-                    plt.title(f"Mean RT by Stimulus Color Hard (Class Data)")
-                    plt.xlabel("Stimulus Color")
-                    plt.ylabel("Mean Response Time (ms)")
-
-                    plt.tight_layout()
-
-                    self.stats_write(my_plot.get_figure())
-                except Exception as e:
-                    self.stats_write(
-                        f'<br><font color="Red">Error while trying to create class comparison graph: {e}</font><br>'
-                    )
-
-            # --------------------------------------------------------------------------
-
-            # Third bar plot (Eccentricity)
-            fig2, ax2 = plt.subplots(figsize=(7, 4), dpi=96)
-            my_eccentricity_plot = sns.barplot(
-                x="StimPos",
-                hue="StimPos",
-                y="RT",
-                data=data,
-                capsize=0.1,
-                ax=ax2,
-                legend=False
-            )
-
-            plt.title(f"Mean RT by Eccentricity, {cond} Condition")
-            plt.xlabel("Eccentricity")
-            plt.ylabel("Mean Response Time (ms)")
-
-            plt.tight_layout()
-
-            # Save the second plot
-            self.stats_write(my_eccentricity_plot.get_figure())
-
             # cleanup figures so they can be garbage collected before next run
             plt.close("all")
 
@@ -955,27 +842,6 @@ class EpicDevice(epicpy_device_base.EpicPyDevice):
 
             self.stats_write(my_plot.get_figure())
 
-            # Second bar plot (Eccentricity)
-            fig2, ax2 = plt.subplots(figsize=(7, 4), dpi=96)
-            my_eccentricity_plot = sns.barplot(
-                x="StimPos",
-                hue="Difficulty",
-                y="RT",
-                data=data,
-                capsize=0.1,
-                ax=ax2,
-                legend=False
-            )
-
-            plt.title(f"Mean RT by Eccentricity by Condition")
-            plt.xlabel("Eccentricity")
-            plt.ylabel("Mean Response Time (ms)")
-
-            plt.tight_layout()
-
-            # Save the second plot
-            self.stats_write(my_eccentricity_plot.get_figure())
-
             # cleanup figures so they can be garbage collected before next run
             plt.close("all")
 
diff --git a/devices/choice/choice_easy_human_data.csv b/devices/devices/choice/choice_easy_human_data.csv
similarity index 100%
rename from devices/choice/choice_easy_human_data.csv
rename to devices/devices/choice/choice_easy_human_data.csv
diff --git a/devices/detection/__init__.py b/devices/devices/choice/encoders/__init__.py
similarity index 100%
rename from devices/detection/__init__.py
rename to devices/devices/choice/encoders/__init__.py
diff --git a/devices/choice/encoders/donders_auditory_encoder.py b/devices/devices/choice/encoders/donders_auditory_encoder.py
similarity index 100%
rename from devices/choice/encoders/donders_auditory_encoder.py
rename to devices/devices/choice/encoders/donders_auditory_encoder.py
diff --git a/devices/detection/encoders/donders_visual_encoder.py b/devices/devices/choice/encoders/donders_visual_encoder.py
similarity index 100%
rename from devices/detection/encoders/donders_visual_encoder.py
rename to devices/devices/choice/encoders/donders_visual_encoder.py
index 213f75088c0d40a8f11ef0ba92044a19b7ebf80c..9ee3cb457028453da3262e1529cf73135401ad71 100644
--- a/devices/detection/encoders/donders_visual_encoder.py
+++ b/devices/devices/choice/encoders/donders_visual_encoder.py
@@ -27,7 +27,6 @@ class VisualEncoder(EPICPyVisualEncoder):
             encoder_name=encoder_name if encoder_name else "VisualEncoder",
             parent=parent,
         )
-
         self.recoding_failure_rate = 0.5
 
     def set_object_property(
@@ -37,6 +36,7 @@ class VisualEncoder(EPICPyVisualEncoder):
         property_value: Symbol,
         encoding_time: int,
     ) -> bool:
+
         """
         Imparts a self.recoding_failure_rate chance of mis-perceiving object colors:
         Yellow->Blue & Green->Red.
diff --git a/devices/choice/images/donders_monitor.png b/devices/devices/choice/images/donders_monitor.png
similarity index 100%
rename from devices/choice/images/donders_monitor.png
rename to devices/devices/choice/images/donders_monitor.png
diff --git a/devices/choice/images/donders_tones.png b/devices/devices/choice/images/donders_tones.png
similarity index 100%
rename from devices/choice/images/donders_tones.png
rename to devices/devices/choice/images/donders_tones.png
diff --git a/devices/choice/rules/choicetask_rules_AV.prs b/devices/devices/choice/rules/choicetask_rules_AV.prs
similarity index 100%
rename from devices/choice/rules/choicetask_rules_AV.prs
rename to devices/devices/choice/rules/choicetask_rules_AV.prs
diff --git a/devices/choice/rules/choicetask_rules_VM.prs b/devices/devices/choice/rules/choicetask_rules_VM.prs
similarity index 100%
rename from devices/choice/rules/choicetask_rules_VM.prs
rename to devices/devices/choice/rules/choicetask_rules_VM.prs
diff --git a/tool_install.py b/tool_install.py
deleted file mode 100644
index 2d8960e4b9cbed55341e99cb4a557e1e5841e429..0000000000000000000000000000000000000000
--- a/tool_install.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# uv-meta: {}
-
-import sys
-import subprocess
-import platform
-from pathlib import Path
-import shutil
-import re
-
-"""
-To run this script:
-1. If you don't have git installed, install it from here: https://git-scm.com/downloads
-2. If you don't have uv installed, install it from here: https://docs.astral.sh/uv/getting-started/installation/
-3. Run this command:
-   uv run tool_install.py
-"""
-
-
-def run_command(command):
-    """Run a command and return the output, or None if it fails."""
-    try:
-        result = subprocess.run(
-            command,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            text=True,
-            check=True,
-        )
-        return result.stdout
-    except subprocess.CalledProcessError as e:
-        print(f"Error running command: {' '.join(command)}", file=sys.stderr)
-        print(e.stderr, file=sys.stderr)
-        return None
-
-
-def ensure_git_installed():
-    """Check if git is installed; if not, alert the user and quit."""
-    if not shutil.which("git"):
-        print("Git is not installed!", file=sys.stderr)
-        print(
-            "Please install git from https://git-scm.com/downloads before trying again.",
-            file=sys.stderr,
-        )
-        sys.exit(1)
-
-
-def get_python_path(version):
-    """
-    Get the path to the specified Python version by querying installed versions using uv.
-    Args:
-        version (str): The Python version to find (e.g., "3.10" or "3.9").
-    Returns:
-        str: The path to the Python executable.
-    """
-    # Run `uv python list --only-installed` to get installed Python versions
-    output = run_command(["uv", "python", "list", "--only-installed"])
-    if not output:
-        print(
-            f"Failed to get installed Python versions. Please ensure uv is installed and configured correctly.",
-            file=sys.stderr,
-        )
-        sys.exit(1)
-
-    # Debug: Print the output for inspection
-    print(f"uv python list output:\n{output}")
-
-    # Split the output into lines and loop through them
-    for line in output.strip().splitlines():
-        # Debug: Print each line being processed
-        print(f"Processing line: {line}")
-
-        if version in line:
-            # Split the line into parts using 2 or more spaces as a delimiter
-            parts = re.split(r"\s{2,}", line)
-            if len(parts) > 1:
-                # Extract the full Python path and remove any symbolic link
-                full_path = parts[-1]
-                python_path = full_path.split(" -> ")[0]
-
-                # Debug: Print the extracted path
-                print(f"Found Python {version} path: {python_path}")
-                return python_path
-
-    # If no matching Python version is found, complain and exit
-    print(
-        f"EPICPy requires Python {version}, but that version could not be located on this system. "
-        f"You can install Python {version} by running this command: uv python install {version}",
-        file=sys.stderr,
-    )
-    sys.exit(1)
-
-
-def is_tool_installed(tool_name):
-    """Check if a tool is listed in the output of 'uv tool list'."""
-    uv_tool_list = run_command(["uv", "tool", "list"])
-    if uv_tool_list and tool_name in uv_tool_list:
-        return True
-    return False
-
-
-def main():
-    ensure_git_installed()
-
-    # Determine the appropriate Python version
-    if platform.system().lower() == "windows":
-        python_path = get_python_path('3.9')
-    else:
-        python_path = get_python_path('3.10')
-
-    # Step 1: Uninstall EPICpy if it is already installed
-    if is_tool_installed("EPICpy"):
-        print("EPICpy is already installed. Uninstalling...")
-        run_command(["uv", "tool", "uninstall", "EPICpy"])
-
-    # Step 2: Install EPICpy using the determined Python path
-    print(f"Installing EPICpy with Python at {python_path}...")
-    run_command(
-        [
-            "uv",
-            "tool",
-            "install",
-            "git+https://www.github.com/travisseymour/EPICpy.git",
-            "--python",
-            python_path,
-        ]
-    )
-
-    # Verify EPICpy installation
-    if is_tool_installed("EPICpy"):
-        print("EPICpy installed successfully! You can run it from the terminal like this: EPICpy")
-    else:
-        print("Failed to install EPICpy. Please check the error above and try again.", file=sys.stderr)
-        sys.exit(1)
-
-    # Step 3: Uninstall epiccoder if it is already installed
-    if is_tool_installed("epiccoder"):
-        print("epiccoder is already installed. Uninstalling...")
-        run_command(["uv", "tool", "uninstall", "epiccoder"])
-
-    # Step 4: Install epiccoder
-    print("Installing epiccoder...")
-    run_command(
-        [
-            "uv",
-            "tool",
-            "install",
-            "git+https://www.github.com/travisseymour/epiccoder.git",
-        ]
-    )
-
-    # Verify epiccoder installation
-    if is_tool_installed("epiccoder"):
-        print("epiccoder installed successfully! You can run it from the terminal like this: epiccoder")
-    else:
-        print("Failed to install epiccoder. Please check the error above and try again.", file=sys.stderr)
-        sys.exit(1)
-
-
-if __name__ == "__main__":
-    main()
-