MultiTaskBattery 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- MultiTaskBattery/__init__.py +4 -0
- MultiTaskBattery/battery.py +223 -0
- MultiTaskBattery/experiment_block.py +340 -0
- MultiTaskBattery/fetch.py +77 -0
- MultiTaskBattery/screen.py +152 -0
- MultiTaskBattery/task_blocks.py +1703 -0
- MultiTaskBattery/task_details.json +1047 -0
- MultiTaskBattery/task_file.py +1833 -0
- MultiTaskBattery/task_table.tsv +23 -0
- MultiTaskBattery/ttl_clock.py +73 -0
- MultiTaskBattery/utils.py +201 -0
- multitaskbattery-1.3.0.dist-info/METADATA +92 -0
- multitaskbattery-1.3.0.dist-info/RECORD +17 -0
- multitaskbattery-1.3.0.dist-info/WHEEL +5 -0
- multitaskbattery-1.3.0.dist-info/entry_points.txt +2 -0
- multitaskbattery-1.3.0.dist-info/licenses/LICENSE +21 -0
- multitaskbattery-1.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# created 2023: Bassel Arafat, Jorn Diedrichsen, Ince Husain
|
|
2
|
+
from psychopy import visual, monitors
|
|
3
|
+
from pyglet.canvas import get_display
|
|
4
|
+
|
|
5
|
+
class Screen:
|
|
6
|
+
def __init__(self, const):
|
|
7
|
+
""" A class to create a screen for the experiment
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
const (module):
|
|
11
|
+
local constants.py module (see example_experiment/constants.py) as example
|
|
12
|
+
Returns:
|
|
13
|
+
self (object):
|
|
14
|
+
an instance of the Screen class
|
|
15
|
+
"""
|
|
16
|
+
self.fullscr = const['fullscr']
|
|
17
|
+
self.units = 'deg'
|
|
18
|
+
self.color = '#808080'
|
|
19
|
+
self.size = const['size'] #[800, 800] #[1440, 900]
|
|
20
|
+
# physical width of the screen and eye-to-screen distance (cm); used to convert deg / cm to pixels.
|
|
21
|
+
# Required: the window works in degrees, so a guessed value would silently change stimulus sizes.
|
|
22
|
+
missing = [key for key in ('width', 'distance') if const.get(key) is None]
|
|
23
|
+
if missing:
|
|
24
|
+
raise ValueError(
|
|
25
|
+
f"{' and '.join(f'screen[{k!r}]' for k in missing)} missing from constants.py. "
|
|
26
|
+
"Set screen['width'] to the physical width of the screen image in cm (measure it) "
|
|
27
|
+
"and screen['distance'] to the eye-to-screen distance in cm.")
|
|
28
|
+
self.distance = const['distance']
|
|
29
|
+
self.width = const['width']
|
|
30
|
+
self.allowGUI = True
|
|
31
|
+
self.screen_number = const['number']
|
|
32
|
+
self.monitor = monitors.Monitor(
|
|
33
|
+
"stimulus",
|
|
34
|
+
distance = self.distance,
|
|
35
|
+
width = self.width,
|
|
36
|
+
)
|
|
37
|
+
self.monitor.setSizePix(self.size) # screen size (not window!) look in display prefs
|
|
38
|
+
self.monitor.saveMon()
|
|
39
|
+
|
|
40
|
+
self.check_monitors()
|
|
41
|
+
|
|
42
|
+
self.window = visual.Window(size = self.size,
|
|
43
|
+
screen = self.screen_number,
|
|
44
|
+
monitor = self.monitor,
|
|
45
|
+
fullscr = self.fullscr,
|
|
46
|
+
units = self.units,
|
|
47
|
+
color = self.color,
|
|
48
|
+
allowGUI = self.allowGUI, allowStencil=True)
|
|
49
|
+
|
|
50
|
+
def check_monitors(self):
|
|
51
|
+
|
|
52
|
+
display = get_display()
|
|
53
|
+
screens = display.get_screens()
|
|
54
|
+
|
|
55
|
+
if self.fullscr and len(screens) <= 1:
|
|
56
|
+
print("Warning: Fullscreen mode is enabled, but you have no external monitor connected.")
|
|
57
|
+
print("Change the constants to not use fullscreen mode or connect an external monitor.")
|
|
58
|
+
print("Quitting the experiment to avoid a frozen screen....")
|
|
59
|
+
exit(1)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def start_screen(self, color='white', height=None, wrap_width=None):
|
|
63
|
+
""" A method to draw a start screen on the screen
|
|
64
|
+
"""
|
|
65
|
+
loading_msg = visual.TextStim(self.window, text="Preparing experiment...", color=color, height=height or 2, wrapWidth=wrap_width or 30)
|
|
66
|
+
loading_msg.draw()
|
|
67
|
+
self.window.flip()
|
|
68
|
+
|
|
69
|
+
def fixation_cross(self, color='white', flip=True):
|
|
70
|
+
""" A method to draw a fixation cross on the screen
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
color (str):
|
|
74
|
+
color of the fixation cross
|
|
75
|
+
flip (bool):
|
|
76
|
+
whether to flip the screen after drawing the fixation cross
|
|
77
|
+
Returns:
|
|
78
|
+
None
|
|
79
|
+
"""
|
|
80
|
+
# Draw the fixation cross
|
|
81
|
+
fixation = visual.ShapeStim(self.window,
|
|
82
|
+
vertices=((0, -0.06), (0, 0.06), (0,0), (-0.04,0), (0.04, 0)),
|
|
83
|
+
lineWidth=20,
|
|
84
|
+
closeShape=False,
|
|
85
|
+
lineColor=color,
|
|
86
|
+
units='norm'
|
|
87
|
+
)
|
|
88
|
+
fixation.draw()
|
|
89
|
+
|
|
90
|
+
# Flip the screen only if flip is True
|
|
91
|
+
if flip:
|
|
92
|
+
self.window.flip()
|
|
93
|
+
|
|
94
|
+
def check_mark(self, color='green', flip=True):
|
|
95
|
+
""" A method to draw a check mark on the screen
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
color (str):
|
|
99
|
+
color of the check mark
|
|
100
|
+
flip (bool):
|
|
101
|
+
whether to flip the screen after drawing the check mark
|
|
102
|
+
Returns:
|
|
103
|
+
None
|
|
104
|
+
"""
|
|
105
|
+
# Draw the check mark as a filled outline (two thick lines leave a notch
|
|
106
|
+
# where they meet), in height units so it keeps its shape on any screen
|
|
107
|
+
check = visual.ShapeStim(self.window,
|
|
108
|
+
vertices=((-0.030, 0.012), (-0.011, -0.009), (0.034, 0.045),
|
|
109
|
+
(0.051, 0.031), (-0.010, -0.042), (-0.046, -0.003)),
|
|
110
|
+
fillColor=color,
|
|
111
|
+
lineColor=None,
|
|
112
|
+
units='height'
|
|
113
|
+
)
|
|
114
|
+
check.draw()
|
|
115
|
+
|
|
116
|
+
# Flip the screen only if flip is True
|
|
117
|
+
if flip:
|
|
118
|
+
self.window.flip()
|
|
119
|
+
|
|
120
|
+
def error_cross(self, color='red', flip=True):
|
|
121
|
+
""" A method to draw an error cross on the screen
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
color (str):
|
|
125
|
+
color of the error cross
|
|
126
|
+
flip (bool):
|
|
127
|
+
whether to flip the screen after drawing the error cross
|
|
128
|
+
Returns:
|
|
129
|
+
None
|
|
130
|
+
"""
|
|
131
|
+
# Draw the fixation cross
|
|
132
|
+
cross_leg1 = visual.ShapeStim(self.window,
|
|
133
|
+
vertices=((-0.04, -0.06), (0.04, 0.06)),
|
|
134
|
+
lineWidth=20,
|
|
135
|
+
closeShape=False,
|
|
136
|
+
lineColor=color,
|
|
137
|
+
units='norm'
|
|
138
|
+
)
|
|
139
|
+
cross_leg1.draw()
|
|
140
|
+
|
|
141
|
+
cross_leg2 = visual.ShapeStim(self.window,
|
|
142
|
+
vertices=((-0.04, 0.06), (0.04, -0.06)),
|
|
143
|
+
lineWidth=20,
|
|
144
|
+
closeShape=False,
|
|
145
|
+
lineColor=color,
|
|
146
|
+
units='norm'
|
|
147
|
+
)
|
|
148
|
+
cross_leg2.draw()
|
|
149
|
+
|
|
150
|
+
# Flip the screen only if flip is True
|
|
151
|
+
if flip:
|
|
152
|
+
self.window.flip()
|