Mouse task#

Dependencies#

Necessary packages#

To run the tests, the following packages are required. They should already be available in the conda environment you use for the project.

  • unittest

  • tkinter

  • pathlib

  • numpy

Note

These packages are already installed and available, thus there is no need to install them again.

Optional packages#

One of the testing scripts allows the user to manually test the game by moving the mouse cursor in a pygame window and to create artificial trajectories that can be later used to test the game automatically. For this, the following packages are required:

  • matplotlib

  • pygame

To install these, please navigate to the root folder of the repository (i.e. to FreelyMovingVR4Mice/), and run the following command:

pip install -e .[testgen]

This will install the optional packages necessary for test generation as specified in the setup.cfg file

Overview#

Some tests have been developed to ensure correct and consistent behavior of the game, more specifically on the mouse_task files, which represents the core of the game logic.

These tests can be found in the FreelyMovingVR4Mice/mouse_task/tests/ folder. The two mains files here are the following:

  1. test_mouse_active_sensing.py: contains some unit tests for the main ActiveSensingTask class to make sure that core functionalities are working as intended.

  2. test_mouse_game_auto.py: leveraging the provided test_trajectories.npy file, this script can be used to automatically test the game by loading the numpy array and simulating the mouse’s actions in the game. The code also performs additional tests to make sure that information about the state of the agent has the correct structure and contains valid values.

  3. test_mouse_game_manual.py: allows the user to manually test the ActiveSensingTask class through a pygame interface where the position inside the Unity game can be controlled by moving the cursor within the pygame window. To simplify things, trigger areas (such as the TT and report boxes) have been highlighted in green. This script also saves the traced trajectories of the mouse cursor in a numpy array (i.e., a *.npy file), which can be later loaded to automatically test the game with the test_mouse_game_auto.py script (below). When performing this manual testing, please run the script below as well as test_mouse_game_auto.py contains additional tests for data integrity and structure of the agent’s state information.

Note

Since trials are randomly generated (i.e. the object can appear on either side of the arena with given probabilities), trials that were successful during manual testing (point 3.) may not have the same outcome when performing automatic testing (point 2.).

Since manual trajectories are already provided, automatic testing should be preferred over manual testing. If the creation of new trajectories is desired, the manual testing script can be used to do so.

How to run tests#

Unit tests#

To run the unit tests, simply run the corresponding python script, i.e. test_mouse_active_sensing.py in the mouse_task/tests/ directory. To do so, you can execute the following command in your terminal:

python mouse_task/tests/test_mouse_active_sensing.py

Warning

It is assumed that your terminal window is open at the root of the FreelyMovingVR4Mice repository and that the correct conda environment is activated with the necessary packages installed. If you are already in the mouse_task/tests/ subfolder, you can directly run:

python test_mouse_active_sensing.py

The unit tests contain several assertions that check crucial aspects of the game logic. Some of the tests include:

  • testing that the object appears on the correct side based on the prob_obj_on_left attribute. Naturally, if prob_obj_on_left = 1.0, then the object will always appear on the left side and on the right side if prob_obj_on_left = 0.0. If the value is 0.5, then the object will appear randomly on either side.

  • testing whether trial blocks are correctly generated

  • testing whether slit sizes are correctly calculated based on the list of values passed to the task.get_slit_sizes([...]) class method.

Game tests#

General requirements#

To run the game tests, you will need to have the Unity game executable file available. Once this taken care of, you’ll be prompted to select the location of such file when running either the manual or automatic testing scripts.

Automatic#

Leveraging the provided test_trajectories.npy file, the automatic testing script can be run to test the game. To do so, simply run the following command in an open terminal window:

python mouse_task/tests/test_mouse_game_auto.py

Warning

It is assumed that your terminal window is open at the root of the FreelyMovingVR4Mice repository and that the correct conda environment is activated with the necessary packages installed. If you are already in the mouse_task/tests/ subfolder, you can directly run:

python test_mouse_game_auto.py

This script will load the numpy array file with the trajectories and simulate the mouse’s actions in the game. The results will be printed in the terminal, showing whether each trial was successful or not.

[Optional] Manual#

In order to manually test the game and/or generate a different set of manual trajectories to use in the automatic testing script, the following procedure can be followed. Run the corresponding python script in the mouse_task/tests/ sub-folder. For instance, the python script can be run with the following command:

python mouse_task/tests/test_mouse_game_manual.py

Warning

It is assumed that your terminal window is open at the root of the FreelyMovingVR4Mice repository and that the conda environment created here is activated and has the necessary packages installed. If you are already in the mouse_task/tests/ subfolder, you can directly run:

python test_mouse_game_manual.py

By executing the above command (either one), you will first be prompted to select the location of the Unity game executable file, then the game will start and a pygame window will pop up as well. Here is a quick demonstration of the testing interface:

interface

Warning

Since the game may boot up in full screen mode, you may have to resize the window to obtain a similar setup to the one shown above.

To exit the pygame and the game window, you just need to press the ESC key on your keyboard. After that, a matplotlib window will pop up displaying the different episode trajectories that have been “drawn” by the cursor during testing. One important feature of the plot is that, at the end of each trajecotory, a green or red star has been added based on whether the “mouse” reported correctly or not respectively.

Note

The testing interface was designed such that it can be quit only during ITI. This means that pressing the ESC key just after reporting and before triggering a new trial is the only way to exit the game without any errors.

How it works#

All testing scripts make use of the unit testing framework that comes with the unittest python library. This allows to create test cases that can be run independently from each other and that can be easily extended as the codebase grows. It also allows the use of mocks and patches to modify or replace parts of the code for testing purposes. For instance, if we want to test a method of a python class that depends on another part of the code (e.g. an external function or another class method), we can “re-define” that part of the code only when running a test to make sure that the behavior of the third-party code does not affect the test results.

For the manual testing pipeline, a pygame interface was used to simulate the mouse moving in the arena with the camera and DLC live tracking. The user can easily move the cursor within the pygame window and the position will be interpolated to Unity arena coordinates and sent to the game. This is done by using a patch (as mentioned above) that replaces the ActiveSensingTask’s get_action(...) method which is responsible for getting the mouse’s position from the DLC Client through the _get_dlc_on_frame(...) method. This way, the live tracking setup necessary on the rig can be easily bypassed for easier usability.

Code currently missing tests#

The testing framework is still early stage and will be continuously updated over time. Thus, some parts of the code logic still remain without unit tests, among which:

  • the scripts under ./mouse_task/dlc_utils/

  • some of the game logic found in the python task scripts under ./mouse_task/

  • most of the scripts found under ./teensyexp/tasks_abc/