MoveByGradientValidator class

This validator gets an image, and allows mouse to move only according to it - from a light color to a darker color (or vice versa).

Note: The validator expects a BMP image in 24-bit format (i.e., RGB format: for each pixel, the image specifies the values of the red, green, and blue components, each on a 0-255 scale).

RGB colors are represented in Python as (red, green, blue) tuples. The tuple can be converted to a single numeric value by calculating

numeric_value = red * 256 * 256 + green * 256 + blue

This is the value used by the validator to determine the gradient.

Features

  • The validator can require movement to comply with ascending or descending RGB directions - see rgb_should_ascend. Yet even when asking for movement in certain direction, you may allow for minor movement in the opposite direction - see max_valid_back_movement.
  • You can tell the validator to use only one of the colors (red/green/blue) to determine the validated gradient. This means that the validator will consider only pixels that are purely on this scale (e.g., if you choose blue, pixels that have non-0 red or green components will be ignored). See single_color for more details.
  • When the movement reaches the highest RGB value (65535 when all colors are used; 255 when a single color is used) and then goes back to a 0-pixel, you may still want to consider this as an ascedning-gradient movement). This would be typically the case when your gradient creates a cyclic path on screen (see the “ImageValidators” sample experiment - have a look at gradient.bmp, which serves for validation in that sample). For more details, see cyclic and the “under the hood” section at the bottom of this page.

Methods and properties:

class trajtracker.validators.MoveByGradientValidator(image, position=(0, 0), rgb_should_ascend=True, max_valid_back_movement=0, cyclic=False, enabled=True)
__init__(image, position=(0, 0), rgb_should_ascend=True, max_valid_back_movement=0, cyclic=False, enabled=True)

Constructor - invoked when you create a new object by writing MoveByGradientValidator()

Parameters:
cyclic

Whether the gradient is cyclic, i.e., allows moving between the darkest to the lightest color

disable_event

The event on which the object should be disabled. This will work only when the object is registered to an EventManager

Type:Event
enable_event

The event on which the object should be enabled. This will work only when the object is registered to an EventManager

Type:Event
enabled

Whether the object is currently functioning or disabled

Type:bool
log_level

Logging level of this object: trajtracker.log_none, log_error (default), log_warn, log_info, log_debug, log_trace

max_valid_back_movement

The maximal valid delta of color-change in the opposite direction that would still be allowed

position

The position of the image: (x,y) tuple/list, indicating the image center For even-sized images, use the Expyriment standard. The position is used to align the image’s coordinate space with that of update_xyt()

reset(time0=None)

Reset the movement validation

rgb_should_ascend

Whether the valid movement is from lower RGB codes to higher RGB codes (True) or vice versa (False)

single_color

Consider only one color out of the three (red / green / blue) available in the image. Each pixel in the image has a value between 0 and 255 for each of the 3 colors. If you set a single color (by setting this attribute to “R”/”G”/”B”), the validator will consider only the value of the selected color. Furthermore, the validator considers only pixels that are purely of this color (e.g., if you select “B”, it means that only pixels with blue=0-255, red=0 and green=0 are relevant for validation).

To accomodate small possible mistakes in the generation of the BMP image, the validator allows for miniscule presence of the irrelevant colors: i.e., if you set single_color=”B”, the validator will consider only pixels with blue=0-255, red<10, and green<10 (the treshold 10 can be changed by setting MoveByGradientValidator.max_irrelevant_color_value); and for this pixels, the validator will consider only the blue value.

update_xyt(position, time_in_trial=None, time_in_session=None)

Validate the movement

Parameters:
  • position – (x,y) coordinates
  • time_in_trial – ignored
  • time_in_session – ignored
Returns:

None if all OK, ExperimentError if error

Under the hood:

  • MoveByGradientValidator.max_irrelevant_color_value (default: 10): define the threshold for a the irrelevant colors when using single_color. If you set single_color=blue, the validator will consider as the relevant (blue) pixels all pixels whose red and green components are not higher than max_irrelevant_color_value.

  • MoveByGradientValidator.cyclic_ratio (default: 5): This definition is relevant when using cyclic = True. The idea is as follows: Each color is a number between 0 and 65,535. Setting “cyclic” means that if the finger/mouse moves from a pixel with value=65,535 to value=0, we want it to be considered as an ascending-gradient movement. But what about moving from 65,535 to 5,000? Did the value ascend by 5,000 (the “cyclic distance”) or descend by 60,535 (the “non-cyclic distance”)? The decision is made as follows: if the cyclic distance is shorter than the non-cyclic distance by more than this ratio (cyclic_ratio), we assume that the movement was in the cyclic direction. in the above example (from 65,535 to 5,000), the cyclic distance is 5000, the non-cyclic distance is 60,535, and indeed 60535 / 5000 > 5, so this movement would be interpreted as cyclic.

    If you use single_color, the same logic applies but the scale is 0-255.