-
Notifications
You must be signed in to change notification settings - Fork 23
Data Format
This page details how MouseTracks stores its tracking data.
All tracking data for a specific profile is stored in a single file with the .mtk extension. These files are located in a Profiles subdirectory within your main application data folder.
The default locations are:
-
Windows:
%APPDATA%\MouseTracks\Profiles\ -
Linux:
~/.local/share/MouseTracks/Profiles/ -
macOS:
~/Library/Application Support/MouseTracks/Profiles/
Each .mtk file is a standard zip archive. You can rename a .mtk file to .zip and open it with any standard archive tool to inspect its contents.
Inside the zip archive, the data is organized into a hierarchical folder structure.
-
config.yaml: A YAML file containing the specific settings for this profile (e.g. whether mouse or keyboard tracking is enabled). -
metadata/: A folder containing simple text files with metadata about the profile, such as its name, timestamps, and ticks. -
data/: The main folder containing the raw tracking data, organised by input type.-
mouse/: Contains mouse data.-
cursor/: Holds data for mouse movement, split intodensity,sequential, andspeedarrays. -
clicks/: Holds data for mouse clicks, categorised by button number (e.g.1for left click) and type (single,double,held).
-
-
keyboard/: Contains keyboard data. -
gamepad/: Contains gamepad data, organised by controller index. -
network/: Contains network usage data.
-
-
stats/: A folder containing daily summary statistics for various activities.
All of the arrays are either 1D or 2D and stored binary NumPy .npy files.
This is a more in depth description of what is tracked. All mouse arrays are separated per resolution.
-
Mouse Track Map: This array represents the timeline of your mouse movements. A global counter starts at 1 and increments every time the mouse moves to a new pixel. The current value of this counter is written to the array at the coordinate corresponding to the mouse's current position, overwriting any previous value. To prevent the counter from growing indefinitely, it is periodically compressed by dividing all values by a set factor.
-
Mouse Speed Map: This array stores the maximum speed recorded at each pixel. Every time the mouse moves, the distance between the last and current position is calculated. This distance value (representing speed) is then written to the array at the new coordinate, but only if it is higher than the value already stored there.
-
Mouse Position Heatmap: This array acts as a simple counter for how many times each pixel has been visited. Every time the mouse moves to a new coordinate, the value in the array at that coordinate is incremented by 1. This builds up over time to show which areas of the screen are most frequently used.
-
Mouse Click Heatmaps: Click data is stored in separate heatmap arrays for each mouse button (left, middle, right, etc.) and for each click type (
single,double,held). When a click occurs, the value in the corresponding array at the cursor's coordinate is incremented by 1. -
Keyboard Key Press & Held Heatmaps: Keyboard input is stored in two 1D arrays:
pressedandheld. The index of the array corresponds to the key's unique code. When a key is pressed, the value at its index in thepressedarray is incremented. For every tick that a key is held down, the value at its index in theheldarray is incremented. -
Gamepad Thumbstick Maps: Stored in the same way as the mouse movement data.
-
Gamepad Button Press & Held Heatmaps: Stored in the same way as the keyboard data.
Here is a basic example of how an mtk file could be parsed in Python using just numpy and pyyaml:
import zipfile
import numpy as np
import yaml
def parse_mtk_file(path_to_mtk_file):
"""Example function to open an .mtk file and extract some data."""
with zipfile.ZipFile(path_to_mtk_file, 'r') as zf:
# Read a metadata text file
profile_name = zf.read('metadata/name').decode('utf-8')
print(f"Profile Name: {profile_name}")
# Load the profile's config file
with zf.open('config.yaml') as config_file:
profile_config = yaml.safe_load(config_file)
print(f"Mouse Tracking Enabled: {profile_config['track_mouse']}")
# Load a NumPy array (e.g. key presses)
# Note: The file might not exist if no keys have been pressed.
try:
with zf.open('data/keyboard/pressed.npy') as npy_file:
key_press_data = np.load(npy_file)
print(f"Number of times A pressed: {key_press_data[ord('A')]}")
except KeyError:
print(f"Number of times A pressed: 0")
if __name__ == '__main__':
parse_mtk_file(os.path.expandvars('%APPDATA%/MouseTracks/Profiles/desktop.mtk'))