psychopy 2024.1.4__py3-none-any.whl → 2024.2.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.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/.DS_Store +0 -0
- psychopy/CHANGELOG.txt +206 -0
- psychopy/GIT_SHA +1 -0
- psychopy/VERSION +1 -0
- psychopy/__init__.py +77 -15
- psychopy/app/Resources/classic/plugin16.png +0 -0
- psychopy/app/Resources/classic/plugin16@2x.png +0 -0
- psychopy/app/Resources/dark/plugin16.png +0 -0
- psychopy/app/Resources/dark/plugin16@2x.png +0 -0
- psychopy/app/Resources/light/plugin16.png +0 -0
- psychopy/app/Resources/light/plugin16@2x.png +0 -0
- psychopy/app/__init__.py +76 -2
- psychopy/app/_psychopyApp.py +126 -101
- psychopy/app/builder/builder.py +14 -10
- psychopy/app/builder/dialogs/__init__.py +8 -8
- psychopy/app/builder/dialogs/dlgsConditions.py +12 -13
- psychopy/app/builder/dialogs/paramCtrls.py +24 -57
- psychopy/app/builder/validators.py +2 -2
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +4 -4
- psychopy/app/connections/sendusage.py +2 -2
- psychopy/app/connections/updates.py +9 -9
- psychopy/app/dialogs.py +34 -2
- psychopy/app/idle.py +31 -0
- psychopy/app/jobs.py +21 -3
- psychopy/app/linuxconfig/__init__.py +9 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4602 -2540
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +53 -43
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1011 -942
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +9415 -5
- psychopy/app/pavlovia_ui/_base.py +33 -3
- psychopy/app/pavlovia_ui/search.py +0 -1
- psychopy/app/plugin_manager/dialog.py +104 -51
- psychopy/app/plugin_manager/packages.py +5 -0
- psychopy/app/plugin_manager/plugins.py +145 -67
- psychopy/app/preferencesDlg.py +8 -8
- psychopy/app/psychopyApp.py +11 -5
- psychopy/app/ribbon.py +124 -14
- psychopy/app/runner/runner.py +6 -1
- psychopy/app/stdout/stdOutRich.py +27 -11
- psychopy/app/themes/icons.py +52 -2
- psychopy/assets/__init__.py +0 -0
- psychopy/assets/click.png +0 -0
- psychopy/assets/clicknext.png +0 -0
- psychopy/assets/next.png +0 -0
- psychopy/assets/psychopy.ico +0 -0
- psychopy/assets/psychopy.png +0 -0
- psychopy/assets/templates/__init__.py +0 -0
- psychopy/assets/touch.png +0 -0
- psychopy/assets/touchnext.png +0 -0
- psychopy/assets/window.ico +0 -0
- psychopy/changes/2023.1.0.md +9 -0
- psychopy/changes/2024.1.0.md +16 -0
- psychopy/changes/__init__.py +0 -0
- psychopy/clock.py +2 -2
- psychopy/colors.py +2 -1
- psychopy/compatibility.py +53 -1
- psychopy/contrib/.DS_Store +0 -0
- psychopy/contrib/configobj/__init__.py +10 -8
- psychopy/data/__init__.py +3 -2
- psychopy/data/base.py +5 -5
- psychopy/data/experiment.py +130 -4
- psychopy/data/routine.py +56 -0
- psychopy/data/staircase.py +2 -2
- psychopy/data/trial.py +559 -97
- psychopy/data/utils.py +56 -21
- psychopy/demos/.DS_Store +0 -0
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +375 -0
- psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +433 -0
- psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
- psychopy/demos/builder/Hardware/.DS_Store +0 -0
- psychopy/demos/builder/Helper Tools/.DS_Store +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/hardware/testSoundLatency.py +2 -2
- psychopy/demos/coder/iohub/.DS_Store +0 -0
- psychopy/demos/coder/misc/hdf5_2_csv +33 -0
- psychopy/event.py +30 -29
- psychopy/experiment/.DS_Store +0 -0
- psychopy/experiment/_experiment.py +6 -6
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/__init__.py +6 -3
- psychopy/experiment/components/_base.py +286 -131
- psychopy/experiment/components/aperture/.DS_Store +0 -0
- psychopy/experiment/components/brush/.DS_Store +0 -0
- psychopy/experiment/components/button/.DS_Store +0 -0
- psychopy/experiment/components/button/__init__.py +5 -1
- psychopy/experiment/components/buttonBox/.DS_Store +0 -0
- psychopy/experiment/components/camera/.DS_Store +0 -0
- psychopy/experiment/components/code/.DS_Store +0 -0
- psychopy/experiment/components/dots/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/__init__.py +92 -30
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/form/__init__.py +6 -2
- psychopy/experiment/components/grating/.DS_Store +0 -0
- psychopy/experiment/components/grating/__init__.py +14 -3
- psychopy/experiment/components/image/.DS_Store +0 -0
- psychopy/experiment/components/image/__init__.py +14 -3
- psychopy/experiment/components/joyButtons/.DS_Store +0 -0
- psychopy/experiment/components/joystick/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/__init__.py +22 -10
- psychopy/experiment/components/microphone/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +59 -39
- psychopy/experiment/components/mouse/.DS_Store +0 -0
- psychopy/experiment/components/mouse/__init__.py +44 -29
- psychopy/experiment/components/movie/.DS_Store +0 -0
- psychopy/experiment/components/movie/__init__.py +1 -1
- psychopy/experiment/components/panorama/.DS_Store +0 -0
- psychopy/experiment/components/parallelOut/.DS_Store +0 -0
- psychopy/experiment/components/patch/.DS_Store +0 -0
- psychopy/experiment/components/polygon/.DS_Store +0 -0
- psychopy/experiment/components/polygon/__init__.py +26 -6
- psychopy/experiment/components/progress/.DS_Store +0 -0
- psychopy/experiment/components/ratingScale/.DS_Store +0 -0
- psychopy/experiment/components/resourceManager/.DS_Store +0 -0
- psychopy/experiment/components/roi/.DS_Store +0 -0
- psychopy/experiment/components/roi/__init__.py +5 -0
- psychopy/experiment/components/routineSettings/.DS_Store +0 -0
- psychopy/experiment/components/routineSettings/__init__.py +57 -10
- psychopy/experiment/components/serialOut/.DS_Store +0 -0
- psychopy/experiment/components/settings/.DS_Store +0 -0
- psychopy/experiment/components/settings/__init__.py +117 -42
- psychopy/experiment/components/slider/.DS_Store +0 -0
- psychopy/experiment/components/sound/.DS_Store +0 -0
- psychopy/experiment/components/sound/__init__.py +54 -19
- psychopy/experiment/components/static/.DS_Store +0 -0
- psychopy/experiment/components/static/__init__.py +1 -1
- psychopy/experiment/components/text/.DS_Store +0 -0
- psychopy/experiment/components/text/__init__.py +28 -3
- psychopy/experiment/components/textbox/.DS_Store +0 -0
- psychopy/experiment/components/textbox/__init__.py +12 -2
- psychopy/experiment/components/unknown/.DS_Store +0 -0
- psychopy/experiment/components/unknown/__init__.py +1 -2
- psychopy/experiment/components/unknownPlugin/.DS_Store +0 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -2
- psychopy/experiment/components/variable/.DS_Store +0 -0
- psychopy/experiment/flow.py +11 -4
- psychopy/experiment/loops.py +85 -37
- psychopy/experiment/params.py +74 -32
- psychopy/experiment/py2js_transpiler.py +8 -1
- psychopy/experiment/routines/.DS_Store +0 -0
- psychopy/experiment/routines/_base.py +102 -22
- psychopy/experiment/routines/counterbalance/.DS_Store +0 -0
- psychopy/experiment/routines/counterbalance/__init__.py +5 -1
- psychopy/experiment/routines/eyetracker_calibrate/.DS_Store +0 -0
- psychopy/experiment/routines/eyetracker_validate/.DS_Store +0 -0
- psychopy/experiment/routines/pavlovia_survey/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/__init__.py +6 -5
- psychopy/experiment/routines/unknown/.DS_Store +0 -0
- psychopy/gui/wxgui.py +4 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/__init__.py +1 -1
- psychopy/hardware/base.py +12 -0
- psychopy/hardware/camera/__init__.py +1 -15
- psychopy/hardware/cedrus.py +10 -11
- psychopy/hardware/crs/colorcal.py +13 -22
- psychopy/hardware/crs/optical.py +10 -20
- psychopy/hardware/emulator.py +17 -14
- psychopy/hardware/eyetracker.py +42 -118
- psychopy/hardware/gammasci.py +4 -15
- psychopy/hardware/keyboard.py +102 -10
- psychopy/hardware/listener.py +3 -0
- psychopy/hardware/microphone.py +148 -18
- psychopy/hardware/minolta.py +8 -15
- psychopy/hardware/photodiode.py +191 -16
- psychopy/hardware/photometer/__init__.py +11 -19
- psychopy/hardware/pr.py +8 -15
- psychopy/hardware/speaker.py +39 -4
- psychopy/info.py +0 -71
- psychopy/iohub/.DS_Store +0 -0
- psychopy/iohub/__init__.py +1 -1
- psychopy/iohub/client/__init__.py +30 -20
- psychopy/iohub/client/keyboard.py +24 -24
- psychopy/iohub/datastore/__init__.py +2 -2
- psychopy/iohub/datastore/util.py +2 -2
- psychopy/iohub/default_config.yaml +1 -1
- psychopy/iohub/devices/.DS_Store +0 -0
- psychopy/iohub/devices/__init__.py +112 -25
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/experiment/default_experiment.yaml +12 -1
- psychopy/iohub/devices/experiment/supported_config_settings.yaml +5 -1
- psychopy/iohub/devices/eyetracker/.DS_Store +0 -0
- psychopy/iohub/devices/eyetracker/__init__.py +46 -0
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +2 -2
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +14 -2
- psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +3 -4
- psychopy/iohub/server.py +2 -2
- psychopy/iohub/start_iohub_process.py +3 -0
- psychopy/iohub/util/__init__.py +62 -70
- psychopy/layout.py +5 -5
- psychopy/logging.py +8 -1
- psychopy/microphone.py +10 -37
- psychopy/platform_specific/__init__.py +0 -2
- psychopy/platform_specific/darwin.py +1 -3
- psychopy/platform_specific/linux.py +31 -33
- psychopy/platform_specific/win32.py +38 -13
- psychopy/plugins/__init__.py +148 -116
- psychopy/plugins/util.py +39 -0
- psychopy/preferences/Darwin.spec +4 -2
- psychopy/preferences/FreeBSD.spec +4 -2
- psychopy/preferences/Linux.spec +4 -2
- psychopy/preferences/Windows.spec +4 -2
- psychopy/preferences/baseNoArch.spec +4 -2
- psychopy/preferences/preferences.py +47 -24
- psychopy/projects/pavlovia.py +47 -4
- psychopy/scripts/psyexpCompile.py +0 -4
- psychopy/session.py +153 -21
- psychopy/sound/__init__.py +31 -21
- psychopy/sound/_base.py +20 -3
- psychopy/sound/audioclip.py +320 -33
- psychopy/sound/backend_ptb.py +47 -58
- psychopy/sound/backend_pygame.py +1 -1
- psychopy/sound/backend_pysound.py +6 -15
- psychopy/sound/transcribe.py +53 -0
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
- psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
- psychopy/tests/data/test_session/.DS_Store +0 -0
- psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
- psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/conftest.py +2 -2
- psychopy/tests/test_app/test_speed.py +4 -1
- psychopy/tests/test_data/test_TrialHandler2.py +146 -1
- psychopy/tests/test_experiment/.DS_Store +0 -0
- psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +3 -3
- psychopy/tests/test_experiment/needs_wx/test_components.py +2 -2
- psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
- psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
- psychopy/tests/test_experiment/test_components/test_base_components.py +58 -0
- psychopy/tests/test_experiment/test_py2js.py +1 -1
- psychopy/tests/test_hardware/test_keyboard.py +31 -0
- psychopy/tests/test_hardware/test_ports.py +1 -11
- psychopy/tests/test_liaison/test_Liaison.py +47 -0
- psychopy/tests/test_misc/test_core.py +5 -0
- psychopy/tests/test_session/test_Session.py +5 -1
- psychopy/tests/test_tools/test_versionchooser.py +39 -8
- psychopy/tests/test_visual/test_all_stimuli.py +0 -97
- psychopy/tests/test_visual/test_image.py +6 -5
- psychopy/tests/test_visual/test_textbox.py +36 -0
- psychopy/tests/utils.py +4 -0
- psychopy/tools/filetools.py +1 -1
- psychopy/tools/pkgtools.py +160 -137
- psychopy/tools/versionchooser.py +10 -10
- psychopy/tools/wizard.py +3 -3
- psychopy/visual/.DS_Store +0 -0
- psychopy/visual/backends/pygletbackend.py +24 -13
- psychopy/visual/basevisual.py +5 -11
- psychopy/visual/button.py +2 -14
- psychopy/visual/helpers.py +5 -5
- psychopy/visual/line.py +1 -2
- psychopy/visual/movie2.py +7 -816
- psychopy/visual/movie3.py +7 -589
- psychopy/visual/movies/__init__.py +8 -11
- psychopy/visual/movies/frame.py +5 -2
- psychopy/visual/movies/players/ffpyplayer_player.py +5 -2
- psychopy/visual/noise.py +8 -7
- psychopy/visual/patch.py +7 -16
- psychopy/visual/radial.py +9 -7
- psychopy/visual/ratingscale.py +8 -1415
- psychopy/visual/secondorder.py +10 -9
- psychopy/visual/shape.py +7 -2
- psychopy/visual/text.py +1 -1
- psychopy/visual/textbox2/textbox2.py +28 -5
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/RECORD +307 -213
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/WHEEL +1 -1
- psychopy/app/Resources/click.png +0 -0
- psychopy/app/Resources/next.png +0 -0
- psychopy/experiment/components/patch/__init__.py +0 -121
- psychopy/experiment/components/patch/classic/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
- psychopy/experiment/components/patch/light/patch.png +0 -0
- psychopy/experiment/components/patch/light/patch@2x.png +0 -0
- psychopy/experiment/components/ratingScale/__init__.py +0 -337
- psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
- psychopy/platform_specific/posix.py +0 -16
- psychopy/tests/test_sound/test_microphone.py +0 -217
- psychopy/tests/test_visual/test_ratingScale.py +0 -299
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@16w.png +0 -0
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@32w.png +0 -0
- /psychopy/{app/Resources → assets}/USB-C.png +0 -0
- /psychopy/{app/Resources → assets}/USB.png +0 -0
- /psychopy/{app/Resources → assets}/creditCard.png +0 -0
- /psychopy/{app/Resources → assets}/default.mp3 +0 -0
- /psychopy/{app/Resources → assets}/default.mp4 +0 -0
- /psychopy/{app/Resources → assets}/default.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct1.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct2.png +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -150,13 +150,22 @@ class MouseComponent(BaseComponent):
|
|
|
150
150
|
" gotValidClick = True\n")
|
|
151
151
|
buff.writeIndentedLines(code % self.params)
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
code =
|
|
153
|
+
# store clicked object if there was one
|
|
154
|
+
code = ""
|
|
155
155
|
for paramName in self._clickableParamsList:
|
|
156
|
-
code +=
|
|
157
|
-
|
|
156
|
+
code += (
|
|
157
|
+
f" %(name)s.clicked_{paramName}.append(obj.{paramName})\n"
|
|
158
|
+
)
|
|
159
|
+
buff.writeIndentedLines(code % self.params)
|
|
160
|
+
|
|
161
|
+
# if storing every click and got an invalid click, store None for all params when there was no valid click
|
|
162
|
+
if self.params['saveMouseState'].val not in ['on valid click', 'never']:
|
|
163
|
+
code = "if not gotValidClick:\n"
|
|
164
|
+
for paramName in self._clickableParamsList:
|
|
165
|
+
code += (
|
|
166
|
+
f" %(name)s.clicked_{paramName}.append(None)\n"
|
|
167
|
+
)
|
|
158
168
|
buff.writeIndentedLines(code % self.params)
|
|
159
|
-
buff.setIndentLevel(-2, relative=True)
|
|
160
169
|
|
|
161
170
|
def _writeCorrectAnsCode(self, buff):
|
|
162
171
|
code = (
|
|
@@ -183,7 +192,7 @@ class MouseComponent(BaseComponent):
|
|
|
183
192
|
"// check whether click was in correct object\n"
|
|
184
193
|
"if (gotValidClick) {\n"
|
|
185
194
|
" corr = 0;\n"
|
|
186
|
-
" corrAns = %(correctAns)s;\n"
|
|
195
|
+
" corrAns = eval( %(correctAns)s);\n"
|
|
187
196
|
" for (let obj of [corrAns]) {\n"
|
|
188
197
|
" if (obj.contains(%(name)s)) {\n"
|
|
189
198
|
" corr = 1;\n"
|
|
@@ -211,22 +220,35 @@ class MouseComponent(BaseComponent):
|
|
|
211
220
|
code = (
|
|
212
221
|
"// check if the mouse was inside our 'clickable' objects\n"
|
|
213
222
|
"gotValidClick = false;\n"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
223
|
+
"%(name)s.clickableObjects = eval(%(clickable)s)\n;"
|
|
224
|
+
"// make sure the mouse's clickable objects are an array\n"
|
|
225
|
+
"if (!Array.isArray(%(name)s.clickableObjects)) {\n"
|
|
226
|
+
" %(name)s.clickableObjects = [%(name)s.clickableObjects];\n"
|
|
227
|
+
"}\n"
|
|
228
|
+
"// iterate through clickable objects and check each\n"
|
|
229
|
+
"for (const obj of %(name)s.clickableObjects) {\n"
|
|
230
|
+
" if (obj.contains(%(name)s)) {\n"
|
|
231
|
+
" gotValidClick = true;\n"
|
|
232
|
+
)
|
|
222
233
|
for paramName in self._clickableParamsList:
|
|
223
|
-
code +=
|
|
224
|
-
|
|
234
|
+
code += (
|
|
235
|
+
f" %(name)s.clicked_{paramName}.push(obj.{paramName});\n"
|
|
236
|
+
)
|
|
237
|
+
code += (
|
|
238
|
+
" }\n"
|
|
239
|
+
"}\n"
|
|
240
|
+
)
|
|
241
|
+
buff.writeIndentedLines(code % self.params)
|
|
225
242
|
|
|
243
|
+
# if storing every click and got an invalid click, store None for all params when there was no valid click
|
|
244
|
+
if self.params['saveMouseState'].val not in ['on valid click', 'never']:
|
|
245
|
+
code = "if (!gotValidClick) {\n"
|
|
246
|
+
for paramName in self._clickableParamsList:
|
|
247
|
+
code += (
|
|
248
|
+
f" %(name)s.clicked_{paramName}.push(null);\n"
|
|
249
|
+
)
|
|
250
|
+
code += "}\n"
|
|
226
251
|
buff.writeIndentedLines(code % self.params)
|
|
227
|
-
for dents in range(dedent):
|
|
228
|
-
buff.setIndentLevel(-1, relative=True)
|
|
229
|
-
buff.writeIndented('}\n')
|
|
230
252
|
|
|
231
253
|
def writeInitCode(self, buff):
|
|
232
254
|
code = ("%(name)s = event.Mouse(win=win)\n"
|
|
@@ -746,14 +768,7 @@ class MouseComponent(BaseComponent):
|
|
|
746
768
|
mouseDataProps.append("clicked_{}".format(paramName))
|
|
747
769
|
# use that set of properties to create set of addData commands
|
|
748
770
|
for property in mouseDataProps:
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
buff.writeIndented(code)
|
|
753
|
-
else:
|
|
754
|
-
# we only had one click so don't return a list
|
|
755
|
-
code = ("if (%s.%s) {"
|
|
756
|
-
" psychoJS.experiment.addData('%s.%s', %s.%s[0])};\n"
|
|
757
|
-
% (name, property, name, property, name, property))
|
|
758
|
-
buff.writeIndented(code)
|
|
771
|
+
code = ("psychoJS.experiment.addData('%s.%s', %s.%s);\n" %
|
|
772
|
+
(name, property, name, property))
|
|
773
|
+
buff.writeIndented(code)
|
|
759
774
|
buff.writeIndentedLines("\n")
|
|
Binary file
|
|
@@ -80,7 +80,7 @@ class MovieComponent(BaseVisualComponent):
|
|
|
80
80
|
|
|
81
81
|
msg = _translate("How loud should audio be played?")
|
|
82
82
|
self.params["volume"] = Param(
|
|
83
|
-
volume, valType='num', inputType="
|
|
83
|
+
volume, valType='num', inputType="single", categ='Playback',
|
|
84
84
|
hint=msg,
|
|
85
85
|
label=_translate("Volume"))
|
|
86
86
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -26,6 +26,7 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
26
26
|
fillColor='white', fillColorSpace='rgb',
|
|
27
27
|
shape='triangle', nVertices=4, vertices="",
|
|
28
28
|
pos=(0, 0), size=(0.5, 0.5), ori=0,
|
|
29
|
+
draggable=False,
|
|
29
30
|
startType='time (s)', startVal=0.0,
|
|
30
31
|
stopType='duration (s)', stopVal=1.0,
|
|
31
32
|
startEstim='', durationEstim=''):
|
|
@@ -90,6 +91,14 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
90
91
|
updates='constant',
|
|
91
92
|
hint=_translate("Which point on the stimulus should be anchored to its exact position?"),
|
|
92
93
|
label=_translate("Anchor"))
|
|
94
|
+
self.params['draggable'] = Param(
|
|
95
|
+
draggable, valType="code", inputType="bool", categ="Layout",
|
|
96
|
+
updates="constant",
|
|
97
|
+
label=_translate("Draggable?"),
|
|
98
|
+
hint=_translate(
|
|
99
|
+
"Should this stimulus be moveble by clicking and dragging?"
|
|
100
|
+
)
|
|
101
|
+
)
|
|
93
102
|
|
|
94
103
|
msg = _translate("What shape is this? With 'regular polygon...' you "
|
|
95
104
|
"can set number of vertices and with 'custom "
|
|
@@ -129,6 +138,14 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
129
138
|
"first value is used, for triangle and rect the [w,h] is as "
|
|
130
139
|
"expected,\n but for higher-order polygons it represents the "
|
|
131
140
|
"[w,h] of the ellipse that the polygon sits on!! ")
|
|
141
|
+
|
|
142
|
+
self.depends.append({
|
|
143
|
+
'dependsOn': "shape", # if...
|
|
144
|
+
'condition': "=='line'", # is...
|
|
145
|
+
'param': "anchor", # then...
|
|
146
|
+
'true': "hide", # should...
|
|
147
|
+
'false': "show", # otherwise...
|
|
148
|
+
})
|
|
132
149
|
|
|
133
150
|
del self.params['color']
|
|
134
151
|
|
|
@@ -155,7 +172,7 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
155
172
|
if vertices in ['line', '2']:
|
|
156
173
|
code = ("%s = visual.Line(\n" % inits['name'] +
|
|
157
174
|
" win=win, name='%s',%s\n" % (inits['name'], unitsStr) +
|
|
158
|
-
"
|
|
175
|
+
" size=%(size)s,\n" % inits)
|
|
159
176
|
elif vertices in ['triangle', '3']:
|
|
160
177
|
code = ("%s = visual.ShapeStim(\n" % inits['name'] +
|
|
161
178
|
" win=win, name='%s',%s\n" % (inits['name'], unitsStr) +
|
|
@@ -186,9 +203,9 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
186
203
|
" win=win, name='%s', vertices=%s,%s\n" % (inits['name'], vertices, unitsStr) +
|
|
187
204
|
" size=%(size)s,\n" % inits)
|
|
188
205
|
|
|
189
|
-
code += (" ori=%(ori)s, pos=%(pos)s, anchor=%(anchor)s,\n"
|
|
190
|
-
" lineWidth=%(lineWidth)s
|
|
191
|
-
" colorSpace=%(colorSpace)s,
|
|
206
|
+
code += (" ori=%(ori)s, pos=%(pos)s, draggable=%(draggable)s, anchor=%(anchor)s,\n"
|
|
207
|
+
" lineWidth=%(lineWidth)s,\n"
|
|
208
|
+
" colorSpace=%(colorSpace)s, lineColor=%(lineColor)s, fillColor=%(fillColor)s,\n"
|
|
192
209
|
" opacity=%(opacity)s, " % inits)
|
|
193
210
|
|
|
194
211
|
depth = -self.getPosInRoutine()
|
|
@@ -276,7 +293,9 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
276
293
|
if self.params['interpolate'].val != 'linear':
|
|
277
294
|
interpolate = 'false'
|
|
278
295
|
|
|
279
|
-
code += (" ori: {ori},
|
|
296
|
+
code += (" ori: {ori}, \n"
|
|
297
|
+
" pos: {pos}, \n"
|
|
298
|
+
" draggable: {draggable}, \n"
|
|
280
299
|
" anchor: {anchor},\n"
|
|
281
300
|
" lineWidth: {lineWidth}, \n"
|
|
282
301
|
" colorSpace: {colorSpace},\n")
|
|
@@ -310,5 +329,6 @@ class PolygonComponent(BaseVisualComponent):
|
|
|
310
329
|
depth=depth,
|
|
311
330
|
interpolate=interpolate,
|
|
312
331
|
nVertices=inits['nVertices'],
|
|
313
|
-
vertices=inits['vertices']
|
|
332
|
+
vertices=inits['vertices'],
|
|
333
|
+
draggable=inits['draggable']
|
|
314
334
|
))
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -301,6 +301,11 @@ class RegionOfInterestComponent(PolygonComponent):
|
|
|
301
301
|
f"if {name}.numLooks:\n"
|
|
302
302
|
f" {currLoop.params['name']}.addData('{name}.timesOn', {name}.timesOn{index})\n"
|
|
303
303
|
f" {currLoop.params['name']}.addData('{name}.timesOff', {name}.timesOff{index})\n"
|
|
304
|
+
f" # calculate and store dwell times i.e. the duration between look onsets and offsets\n"
|
|
305
|
+
f" {name}.dwellTime = 0.0\n"
|
|
306
|
+
f" for i in range(len({name}.timesOn)):\n"
|
|
307
|
+
f" {name}.dwellTime += {name}.timesOff[i] - {name}.timesOn[i]\n"
|
|
308
|
+
f" {currLoop.params['name']}.addData('{name}.dwellTime', {name}.dwellTime)\n"
|
|
304
309
|
f"else:\n"
|
|
305
310
|
f" {currLoop.params['name']}.addData('{name}.timesOn', \"\")\n"
|
|
306
311
|
f" {currLoop.params['name']}.addData('{name}.timesOff', \"\")\n"
|
|
Binary file
|
|
@@ -19,9 +19,10 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
19
19
|
self, exp, parentName,
|
|
20
20
|
# Basic
|
|
21
21
|
name='',
|
|
22
|
-
skipIf="",
|
|
23
|
-
# Description
|
|
24
22
|
desc="",
|
|
23
|
+
# Flow
|
|
24
|
+
skipIf="",
|
|
25
|
+
forceNonSlip=False,
|
|
25
26
|
# Window
|
|
26
27
|
useWindowParams=False,
|
|
27
28
|
color="$[0,0,0]",
|
|
@@ -65,6 +66,17 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
65
66
|
self.params['durationEstim'].categ = "Flow"
|
|
66
67
|
|
|
67
68
|
# --- Flow params ---
|
|
69
|
+
self.order += [
|
|
70
|
+
"forceNonSlip",
|
|
71
|
+
"skipIf",
|
|
72
|
+
]
|
|
73
|
+
self.params['forceNonSlip'] = Param(
|
|
74
|
+
forceNonSlip, valType="code", inputType="bool", categ="Flow",
|
|
75
|
+
hint=_translate(
|
|
76
|
+
"If this Routine ended by hitting its max duration, reset the timer by subtracting the max duration rather than resetting to 0. Only tick this if you're sure you know how long the Routine is going to take, otherwise you'll get incorrect timestamps in the next Routine!"
|
|
77
|
+
),
|
|
78
|
+
label=_translate("Non-slip timing")
|
|
79
|
+
)
|
|
68
80
|
self.params['skipIf'] = Param(
|
|
69
81
|
skipIf, valType='code', inputType="single", categ='Flow',
|
|
70
82
|
updates='constant',
|
|
@@ -146,17 +158,34 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
146
158
|
def writeRoutineStartCode(self, buff):
|
|
147
159
|
# Sanitize
|
|
148
160
|
params = self.params.copy()
|
|
149
|
-
|
|
161
|
+
if params['stopVal'] in ("None", None, ""):
|
|
162
|
+
params['stopVal'].val = "None"
|
|
163
|
+
# store start times
|
|
164
|
+
code = (
|
|
165
|
+
"# store start times for %(name)s\n"
|
|
166
|
+
"%(name)s.tStartRefresh = win.getFutureFlipTime(clock=globalClock)\n"
|
|
167
|
+
"%(name)s.tStart = globalClock.getTime(format='float')\n"
|
|
168
|
+
"%(name)s.status = STARTED\n"
|
|
169
|
+
)
|
|
170
|
+
buff.writeIndentedLines(code % self.params)
|
|
171
|
+
# add to data file if requested
|
|
150
172
|
if self.params['saveStartStop']:
|
|
151
173
|
code = (
|
|
152
|
-
|
|
174
|
+
"thisExp.addData('%(name)s.started', %(name)s.tStart)\n"
|
|
175
|
+
)
|
|
176
|
+
buff.writeIndentedLines(code % params)
|
|
177
|
+
# calculate expected Routine duration
|
|
178
|
+
if self.params['stopType'] == "duration (s)":
|
|
179
|
+
code = (
|
|
180
|
+
"%(name)s.maxDuration = %(stopVal)s\n"
|
|
153
181
|
)
|
|
154
182
|
buff.writeIndentedLines(code % params)
|
|
155
183
|
# Skip Routine if condition is met
|
|
156
184
|
if params['skipIf'].val not in ('', None, -1, 'None'):
|
|
157
185
|
code = (
|
|
158
|
-
"# skip
|
|
159
|
-
"
|
|
186
|
+
"# skip Routine %(name)s if its 'Skip if' condition is True\n"
|
|
187
|
+
"%(name)s.skipped = continueRoutine and not (%(skipIf)s)\n"
|
|
188
|
+
"continueRoutine = %(name)s.skipped\n"
|
|
160
189
|
)
|
|
161
190
|
buff.writeIndentedLines(code % params)
|
|
162
191
|
# Change window appearance for this Routine (if requested)
|
|
@@ -172,6 +201,8 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
172
201
|
def writeRoutineStartCodeJS(self, buff):
|
|
173
202
|
# Sanitize
|
|
174
203
|
params = self.params.copy()
|
|
204
|
+
if params['stopVal'] in ("None", None, ""):
|
|
205
|
+
params['stopVal'].val = "None"
|
|
175
206
|
# Store Routine start time (UTC)
|
|
176
207
|
if self.params['saveStartStop']:
|
|
177
208
|
code = (
|
|
@@ -183,6 +214,13 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
183
214
|
code = (
|
|
184
215
|
"// skip this Routine if its 'Skip if' condition is True\n"
|
|
185
216
|
"continueRoutine = continueRoutine && !(%(skipIf)s);\n"
|
|
217
|
+
"maxDurationReached = false\n"
|
|
218
|
+
)
|
|
219
|
+
buff.writeIndentedLines(code % params)
|
|
220
|
+
# calculate expected Routine duration
|
|
221
|
+
if self.params['stopType'] == "duration (s)":
|
|
222
|
+
code = (
|
|
223
|
+
"%(name)sMaxDuration = %(stopVal)s\n"
|
|
186
224
|
)
|
|
187
225
|
buff.writeIndentedLines(code % params)
|
|
188
226
|
# Change window appearance for this Routine (if requested)
|
|
@@ -224,7 +262,8 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
224
262
|
# Stop after given number of seconds
|
|
225
263
|
code = (
|
|
226
264
|
f"# is it time to end the Routine? (based on local clock)\n"
|
|
227
|
-
f"if tThisFlip > %(
|
|
265
|
+
f"if tThisFlip > %(name)s.maxDuration-frameTolerance:\n"
|
|
266
|
+
f" %(name)s.maxDurationReached = True\n"
|
|
228
267
|
)
|
|
229
268
|
elif self.params['stopType'].val == 'frame N':
|
|
230
269
|
# Stop at given frame num
|
|
@@ -261,7 +300,8 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
261
300
|
# Stop after given number of seconds
|
|
262
301
|
code = (
|
|
263
302
|
f"// is it time to end the Routine? (based on local clock)\n"
|
|
264
|
-
f"if (t > %(
|
|
303
|
+
f"if (t > %(name)sMaxDuration) {{\n"
|
|
304
|
+
f" %(name)sMaxDurationReached = true\n"
|
|
265
305
|
)
|
|
266
306
|
elif self.params['stopType'].val == 'frame N':
|
|
267
307
|
# Stop at given frame num
|
|
@@ -287,10 +327,17 @@ class RoutineSettingsComponent(BaseComponent):
|
|
|
287
327
|
|
|
288
328
|
def writeRoutineEndCode(self, buff):
|
|
289
329
|
params = self.params.copy()
|
|
290
|
-
#
|
|
330
|
+
# store stop times
|
|
331
|
+
code = (
|
|
332
|
+
"# store stop times for %(name)s\n"
|
|
333
|
+
"%(name)s.tStop = globalClock.getTime(format='float')\n"
|
|
334
|
+
"%(name)s.tStopRefresh = tThisFlipGlobal\n"
|
|
335
|
+
)
|
|
336
|
+
buff.writeIndentedLines(code % params)
|
|
337
|
+
# add to data file if requested
|
|
291
338
|
if self.params['saveStartStop']:
|
|
292
339
|
code = (
|
|
293
|
-
"thisExp.addData('%(name)s.stopped',
|
|
340
|
+
"thisExp.addData('%(name)s.stopped', %(name)s.tStop)\n"
|
|
294
341
|
)
|
|
295
342
|
buff.writeIndentedLines(code % params)
|
|
296
343
|
# Restore window appearance after this Routine (if changed)
|
|
Binary file
|
|
Binary file
|