top of page
TrajTracker Paradigms: Sample scripts
Trajectory-sensitive objects

This script demonstrates how to write a custom function that continuously performs operations based on the finger's current position. In this example, we use the position information in a very basic way: we just store it, and when the trial ends - use this stored information to calculate the trajectory length.

​

To accomplish this, TrajTracker Paradigms has a notion of trajectory-sensitive objects. Such objects will be informed when the trial starts, and will then be informed whenever the finger moves.

​

To create a trajectory-sensitive object, define a class that supports the two following methods:

reset(self, time0)

update_xyt(self, position, time_in_trial, time_in_session)

​

Note that the basic trajectory tracking functionality (tracking the finger throughout the trial and saving this to a CSV file) is already provided as part of TrajTracker Paradigms, so you don't need to take care of that.

import numpy as np

 

import expyriment as xpy

 

import trajtracker as ttrk

import trajtrackerp as ttrkp

from trajtrackerp import num2pos, common

 

 

if not xpy.misc.is_android_running():

    xpy.control.defaults.window_mode = True

    ttrk.log_to_console = True

 

ttrk.env.default_log_level = ttrk.log_info

 

 

config = num2pos.Config("Num2Pos(D+U)",

                        max_movement_time=2,

                        max_numberline_value=100,

                        data_source=range(101) * 2,

                        text_target_height=0.5)

 

#=====================================================================

 

msg = xpy.stimuli.TextBox(text="", size=(200, 40), text_font="Arial", text_size=15,

                          text_colour=xpy.misc.constants.C_GREEN)

 

class TrajectorySensitiveObject(object):

 

    def reset(self, time0):

        self._trajectory = []

 

    def update_xyt(self, position, time_in_trial, time_in_session):

        self._trajectory.append(position)

 

    def calc_trajectory_length(self):

        dx = np.diff([pos[0] for pos in self._trajectory])

        dy = np.diff([pos[1] for pos in self._trajectory])

        segments = np.sqrt(dx ** 2 + dy ** 2)

        return sum(segments)

 

tso = TrajectorySensitiveObject()

 

def on_finger_stopped_moving(time_in_trial, time_in_session):

    print(">>>>>>> Finger stopped moving")

    length = tso.calc_trajectory_length()

    print("Trajectory length: {:}".format(length))

    msg.text = "Length: {:}".format(int(length))

 

#===========================================================================================

 

#-- Initialize & start the Expyriment

exp = ttrk.initialize()

xpy.control.start(exp)

 

if not xpy.misc.is_android_running():

    exp.mouse.show_cursor()

 

#-- Get subject info

(subj_id, subj_name) = ttrkp.common.get_subject_name_id()

 

#-- Initialize the experiment objects

exp_info = num2pos.ExperimentInfo(config, exp, subj_id, subj_name)

num2pos.create_experiment_objects(exp_info)

common.register_to_event_manager(exp_info)

 

#-- Set position of custom textboxes (this can only be done now, after the experiment was initialized)

msg.position = -exp_info.screen_size[0]/2 + msg.size[0]/2 + 10, -exp_info.screen_size[1]/2 + msg.size[1]/2 + 10

 

#-- Add custom objects

exp_info.stimuli.add(msg)   # So present() is repeatedly invoked for msg2

exp_info.add_trajectory_sensitive_object(tso)  # So tso.reset() and tso.update_xyt() are called

 

 

#-- When the finger stopped moving, update the trajectory information

exp_info.event_manager.register_operation(event=common.FINGER_STOPPED_MOVING,

                                          operation=on_finger_stopped_moving,

                                          recurring=True,

                                          description="Show trajectory data")

 

#-- Run the experiment

num2pos.run_trials(exp_info)

 

#-- Shutdown Expyriment

xpy.control.end()

bottom of page