psychopy 2024.2.1__py3-none-any.whl → 2024.2.5__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 +204 -0
- psychopy/GIT_SHA +1 -1
- psychopy/VERSION +1 -1
- psychopy/__init__.py +10 -1
- psychopy/__init__.py.orig +65 -0
- psychopy/app/.DS_Store +0 -0
- psychopy/app/Resources/.DS_Store +0 -0
- psychopy/app/_psychopyApp.py +11 -3
- psychopy/app/appData.spec +1 -1
- psychopy/app/builder/builder.py +1 -1
- psychopy/app/builder/builder.py.orig +3932 -0
- psychopy/app/builder/dialogs/__init__.py.orig +1679 -0
- psychopy/app/builder/dialogs/paramCtrls.py +1 -1
- psychopy/app/builder/dialogs/paramCtrls.py.orig +713 -0
- psychopy/app/colorpicker/__init__.py.orig +411 -0
- psychopy/app/cortex.log +0 -0
- psychopy/app/jobs.py +8 -1
- psychopy/app/locale/ar_001/.DS_Store +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +792 -1816
- psychopy/app/plugin_manager/dialog.py +9 -7
- psychopy/app/ribbon.py +2 -1
- psychopy/app/runner/runner.py +25 -13
- psychopy/clock.py +8 -4
- psychopy/core.py.orig +169 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +330 -0
- psychopy/demos/builder/Tools/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +38 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +3418 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +2 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +15 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +562 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
- psychopy/demos/coder/iohub/.iohpid +1 -0
- psychopy/demos/coder/iohub/eyetracking/.iohpid +1 -0
- psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/.DS_Store +0 -0
- psychopy/experiment/_experiment.py +32 -7
- psychopy/experiment/_experiment.py.orig +1032 -0
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/_base.py +13 -4
- psychopy/experiment/components/_base.py.orig +823 -0
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +10 -1
- psychopy/experiment/components/microphone/__init__.py.orig +490 -0
- psychopy/experiment/components/polygon/__init__.py +21 -22
- psychopy/experiment/components/settings/__init__.py +13 -14
- psychopy/experiment/components/settings/__init__.py.orig +1337 -0
- psychopy/experiment/components/textbox/__init__.py.orig +310 -0
- psychopy/experiment/components/webcam/.DS_Store +0 -0
- psychopy/experiment/components/webcam/light/.DS_Store +0 -0
- psychopy/experiment/flow.py +10 -8
- psychopy/experiment/loops.py.orig +829 -0
- psychopy/experiment/params.py +8 -3
- psychopy/experiment/params.py.orig +408 -0
- psychopy/experiment/routine.py.orig +503 -0
- psychopy/experiment/routines/_base.py +15 -6
- psychopy/experiment/routines/counterbalance/__init__.py +1 -0
- psychopy/gui/qtgui.py +14 -7
- psychopy/gui/util.py +10 -14
- psychopy/gui/wxgui.py +10 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/brainproducts.py.orig +680 -0
- psychopy/hardware/iolab.py.orig +238 -0
- psychopy/hardware/manager.py +1 -1
- psychopy/hardware/photodiode.py +59 -27
- psychopy/hardware/speaker.py +4 -4
- psychopy/iohub/client/__init__.py +17 -0
- psychopy/iohub/client/keyboard.py +5 -0
- psychopy/iohub/datastore/__init__.py.orig +443 -0
- psychopy/iohub/datastore/util.py.orig +692 -0
- psychopy/iohub/devices/mouse/darwin.py.orig +427 -0
- psychopy/iohub/devices/mouse/linux2.py +4 -0
- psychopy/iohub/devices/mouse/linux2.py.orig +198 -0
- psychopy/iohub/devices/mouse/win32.py +5 -0
- psychopy/preferences/.DS_Store +0 -0
- psychopy/projects/pavlovia.py +10 -3
- psychopy/projects/pavlovia.py.orig +1295 -0
- psychopy/sound/backend_ptb.py +22 -5
- psychopy/sound/transcribe.py +24 -4
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestCircle_fill_local.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
- psychopy/tests/data/aperture1_norm_local.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_height_local.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_norm_local.png +0 -0
- psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
- psychopy/tests/data/blend_add_height_local.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
- psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
- psychopy/tests/data/blend_add_norm_local.png +0 -0
- psychopy/tests/data/blend_add_stencil_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
- psychopy/tests/data/circleHex_height_local.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
- psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
- psychopy/tests/data/circleHex_norm_local.png +0 -0
- psychopy/tests/data/circleHex_stencil_local.png +0 -0
- psychopy/tests/data/color_comparison_local.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/dots_height_local.png +0 -0
- psychopy/tests/data/dots_normAddBlend_local.png +0 -0
- psychopy/tests/data/dots_normHexbackground_local.png +0 -0
- psychopy/tests/data/dots_normNoShade_local.png +0 -0
- psychopy/tests/data/dots_norm_local.png +0 -0
- psychopy/tests/data/dots_stencil_local.png +0 -0
- psychopy/tests/data/elarray1_height_local.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
- psychopy/tests/data/elarray1_norm_local.png +0 -0
- psychopy/tests/data/elarray1_stencil_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
- psychopy/tests/data/gabor1_height_local.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
- psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
- psychopy/tests/data/gabor1_norm_local.png +0 -0
- psychopy/tests/data/gabor1_stencil_local.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_height_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
- psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
- psychopy/tests/data/movFrame1_stencil_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/numpyImage_height_local.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
- psychopy/tests/data/numpyImage_norm_local.png +0 -0
- psychopy/tests/data/numpyImage_stencil_local.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
- psychopy/tests/data/shape2_1_norm_local.png +0 -0
- psychopy/tests/data/shape2_1_stencil_local.png +0 -0
- psychopy/tests/data/test_loaded_namespace/test_counterbalance.psyexp +142 -0
- psychopy/tests/data/test_loaded_namespace/test_custom_missing.psyexp +129 -0
- psychopy/tests/data/test_loaded_namespace/test_missing_counterbalance.psyexp +116 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_exp.psyexp +181 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_missing.psyexp +140 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_name_calibration.psyexp +164 -0
- psychopy/tests/data/text1_height_local.png +0 -0
- psychopy/tests/data/text1_normAddBlend_local.png +0 -0
- psychopy/tests/data/text1_normHexbackground_local.png +0 -0
- psychopy/tests/data/text1_norm_local.png +0 -0
- psychopy/tests/data/text1_stencil_local.png +0 -0
- psychopy/tests/data/wedge1_height_local.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
- psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
- psychopy/tests/data/wedge1_norm_local.png +0 -0
- psychopy/tests/data/wedge1_stencil_local.png +0 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +177 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +168 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
- psychopy/tests/test_data/.DS_Store +0 -0
- psychopy/tests/test_experiment/test_experiment.py +96 -0
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +68 -0
- psychopy/tests/test_tools/test_arraytools.py +112 -0
- psychopy/tests/test_visual/test_image.py.orig +219 -0
- psychopy/tools/arraytools.py +47 -0
- psychopy/tools/versionchooser.py +1 -1
- psychopy/visual/backends/pygletbackend.py +26 -8
- psychopy/visual/basevisual.py.orig +1723 -0
- psychopy/visual/form.py.orig +1181 -0
- psychopy/visual/text.py.orig +752 -0
- psychopy/visual/textbox2/textbox2.py.orig +1315 -0
- psychopy/visual/window.py +13 -5
- psychopy/visual/windowwarp.py.orig +463 -0
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.5.dist-info}/METADATA +9 -9
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.5.dist-info}/RECORD +220 -84
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.5.dist-info}/WHEEL +1 -1
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.5.dist-info}/entry_points.txt +2 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy-2024.2.1.dist-info/licenses/AUTHORS.md +0 -138
- /psychopy/{app/locale/es_ES/LC_MESSAGE → demos/builder}/.DS_Store +0 -0
- /psychopy/{visual → demos/builder/Experiments}/.DS_Store +0 -0
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -68,7 +68,6 @@ class EnvironmentManagerDlg(wx.Dialog):
|
|
|
68
68
|
|
|
69
69
|
self.notebook.ChangeSelection(0)
|
|
70
70
|
|
|
71
|
-
|
|
72
71
|
@staticmethod
|
|
73
72
|
def getPackageVersionInfo(packageName):
|
|
74
73
|
"""Query packages for available versions.
|
|
@@ -278,10 +277,13 @@ class EnvironmentManagerDlg(wx.Dialog):
|
|
|
278
277
|
)
|
|
279
278
|
else:
|
|
280
279
|
command.append('--user')
|
|
281
|
-
|
|
280
|
+
|
|
282
281
|
# add other options to the command
|
|
283
282
|
command += ['--prefer-binary', '--no-input', '--no-color']
|
|
284
|
-
|
|
283
|
+
|
|
284
|
+
# disable pip version check
|
|
285
|
+
command += ['--disable-pip-version-check']
|
|
286
|
+
|
|
285
287
|
# write command to output panel
|
|
286
288
|
self.output.writeCmd(" ".join(command))
|
|
287
289
|
# append own name to extra
|
|
@@ -359,7 +361,7 @@ class EnvironmentManagerDlg(wx.Dialog):
|
|
|
359
361
|
# write installation termination statement
|
|
360
362
|
msg = "Installation complete"
|
|
361
363
|
if 'pipname' in self.pipProcess.extra:
|
|
362
|
-
msg =
|
|
364
|
+
msg = "Finished installing %(pipname)s" % self.pipProcess.extra
|
|
363
365
|
self.output.writeTerminus(msg)
|
|
364
366
|
|
|
365
367
|
# if we have a plugin, write additional plugin information post-install
|
|
@@ -411,12 +413,12 @@ class EnvironmentManagerDlg(wx.Dialog):
|
|
|
411
413
|
# refresh view
|
|
412
414
|
pkgtools.refreshPackages()
|
|
413
415
|
self.pluginMgr.updateInfo()
|
|
414
|
-
|
|
416
|
+
|
|
415
417
|
def onUninstallExit(self, pid, exitCode):
|
|
416
418
|
# write installation termination statement
|
|
417
419
|
msg = "Uninstall complete"
|
|
418
420
|
if 'pipname' in self.pipProcess.extra:
|
|
419
|
-
msg =
|
|
421
|
+
msg = "Finished uninstalling %(pipname)s" % self.pipProcess.extra
|
|
420
422
|
self.output.writeTerminus(msg)
|
|
421
423
|
# clear pip process
|
|
422
424
|
self.pipProcess = None
|
|
@@ -435,7 +437,7 @@ class EnvironmentManagerDlg(wx.Dialog):
|
|
|
435
437
|
# if they change their mind, cancel closing
|
|
436
438
|
if dlg.ShowModal() == wx.ID_NO:
|
|
437
439
|
return
|
|
438
|
-
|
|
440
|
+
|
|
439
441
|
if evt is not None:
|
|
440
442
|
evt.Skip()
|
|
441
443
|
|
psychopy/app/ribbon.py
CHANGED
|
@@ -467,7 +467,8 @@ class FrameRibbonButton(wx.Button, handlers.ThemeMixin):
|
|
|
467
467
|
wx.Button.__init__(self, parent, style=wx.BORDER_NONE | style, size=(w, 44))
|
|
468
468
|
self.SetMinSize((40, 44))
|
|
469
469
|
# set label
|
|
470
|
-
|
|
470
|
+
if label and style | wx.BU_NOTEXT != style:
|
|
471
|
+
self.SetLabelText(label)
|
|
471
472
|
# set tooltip
|
|
472
473
|
if tooltip and style | wx.BU_NOTEXT == style:
|
|
473
474
|
# if there's no label, include it in the tooltip
|
psychopy/app/runner/runner.py
CHANGED
|
@@ -490,7 +490,6 @@ class RunnerPanel(wx.Panel, ScriptProcess, handlers.ThemeMixin):
|
|
|
490
490
|
|
|
491
491
|
# setup ribbon
|
|
492
492
|
self.ribbon = RunnerRibbon(self)
|
|
493
|
-
self.ribbon.buttons['pyswitch'].setMode(0)
|
|
494
493
|
self.mainSizer.Add(self.ribbon, border=0, flag=wx.EXPAND | wx.ALL)
|
|
495
494
|
|
|
496
495
|
# Setup splitter
|
|
@@ -684,11 +683,13 @@ class RunnerPanel(wx.Panel, ScriptProcess, handlers.ThemeMixin):
|
|
|
684
683
|
# get relevant paths
|
|
685
684
|
htmlPath = str(self.currentFile.parent / self.outputPath)
|
|
686
685
|
jsFile = self.currentFile.parent / (self.currentFile.stem + ".js")
|
|
687
|
-
#
|
|
688
|
-
if
|
|
689
|
-
generateScript(
|
|
690
|
-
|
|
691
|
-
|
|
686
|
+
# regenerate JS file
|
|
687
|
+
if self.currentFile.suffix == ".psyexp":
|
|
688
|
+
generateScript(
|
|
689
|
+
outfile=str(jsFile),
|
|
690
|
+
exp=self.loadExperiment(),
|
|
691
|
+
target="PsychoJS"
|
|
692
|
+
)
|
|
692
693
|
# start server
|
|
693
694
|
self.startServer(htmlPath, port=port)
|
|
694
695
|
# open experiment
|
|
@@ -841,25 +842,36 @@ class RunnerPanel(wx.Panel, ScriptProcess, handlers.ThemeMixin):
|
|
|
841
842
|
del self.entries[self.currentFile] # remove from our tracking dictionary
|
|
842
843
|
self.expCtrl.DeleteItem(self.currentSelection) # from wx control
|
|
843
844
|
self.app.updateWindowMenu()
|
|
844
|
-
|
|
845
|
-
def
|
|
845
|
+
|
|
846
|
+
def updateRunModeIcons(self, evt=None):
|
|
846
847
|
"""
|
|
847
|
-
Function to
|
|
848
|
+
Function to update run/pilot icons according to run mode
|
|
848
849
|
"""
|
|
849
|
-
mode =
|
|
850
|
-
# update buttons
|
|
850
|
+
mode = self.ribbon.buttons['pyswitch'].mode
|
|
851
851
|
# show/hide run buttons
|
|
852
852
|
for key in ("pyrun", "jsrun"):
|
|
853
853
|
self.ribbon.buttons[key].Show(mode)
|
|
854
854
|
# hide/show pilot buttons
|
|
855
855
|
for key in ("pypilot", "jspilot"):
|
|
856
856
|
self.ribbon.buttons[key].Show(not mode)
|
|
857
|
+
# update
|
|
858
|
+
self.ribbon.Layout()
|
|
859
|
+
|
|
860
|
+
def onRunModeToggle(self, evt):
|
|
861
|
+
"""
|
|
862
|
+
Function to execute when switching between pilot and run modes
|
|
863
|
+
"""
|
|
864
|
+
mode = evt.GetInt()
|
|
865
|
+
# update buttons
|
|
866
|
+
self.updateRunModeIcons()
|
|
857
867
|
# update experiment mode
|
|
858
868
|
if self.currentExperiment is not None:
|
|
859
869
|
# find any Builder windows with this experiment open
|
|
860
870
|
for frame in self.app.getAllFrames(frameType='builder'):
|
|
861
871
|
if frame.exp == self.currentExperiment:
|
|
862
|
-
frame.ribbon.buttons['pyswitch'].setMode(mode)
|
|
872
|
+
frame.ribbon.buttons['pyswitch'].setMode(mode, silent=True)
|
|
873
|
+
if hasattr(frame, "updateRunModeIcons"):
|
|
874
|
+
frame.updateRunModeIcons()
|
|
863
875
|
# update current selection
|
|
864
876
|
runMode = "pilot"
|
|
865
877
|
if mode:
|
|
@@ -902,7 +914,7 @@ class RunnerPanel(wx.Panel, ScriptProcess, handlers.ThemeMixin):
|
|
|
902
914
|
# disable stop
|
|
903
915
|
self.ribbon.buttons['pystop'].Disable()
|
|
904
916
|
# switch mode
|
|
905
|
-
self.ribbon.buttons['pyswitch'].setMode(runMode == "run"
|
|
917
|
+
self.ribbon.buttons['pyswitch'].setMode(runMode == "run")
|
|
906
918
|
# update
|
|
907
919
|
self.updateAlerts()
|
|
908
920
|
self.app.updateWindowMenu()
|
psychopy/clock.py
CHANGED
|
@@ -332,14 +332,18 @@ class Clock(MonotonicClock):
|
|
|
332
332
|
self._epochTimeAtLastReset -= t
|
|
333
333
|
|
|
334
334
|
def add(self, t):
|
|
335
|
-
"""
|
|
335
|
+
"""
|
|
336
|
+
DEPRECATED: use .addTime() instead
|
|
336
337
|
|
|
337
338
|
This function adds time TO THE BASE (t0) which, counterintuitively,
|
|
338
339
|
reduces the apparent time on the clock
|
|
339
340
|
"""
|
|
340
|
-
logging.
|
|
341
|
-
|
|
342
|
-
|
|
341
|
+
psychopy.logging.log(msg=(
|
|
342
|
+
"Clock.add() is deprecated in favor of .addTime() due to the counterintuitive design "
|
|
343
|
+
"(it added time to the baseline, which reduced the values returned from getTime() )"
|
|
344
|
+
),
|
|
345
|
+
level=psychopy.logging.DEPRECATION
|
|
346
|
+
)
|
|
343
347
|
self._timeAtLastReset += t
|
|
344
348
|
self._epochTimeAtLastReset += t
|
|
345
349
|
|
psychopy/core.py.orig
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""Basic functions, including timing, rush (imported), quit
|
|
5
|
+
"""
|
|
6
|
+
# Part of the PsychoPy library
|
|
7
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2021 Open Science Tools Ltd.
|
|
8
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
import threading
|
|
12
|
+
import subprocess
|
|
13
|
+
import shlex
|
|
14
|
+
import locale
|
|
15
|
+
|
|
16
|
+
# some things are imported just to be accessible within core's namespace
|
|
17
|
+
from psychopy.clock import (MonotonicClock, Clock, CountdownTimer,
|
|
18
|
+
wait, monotonicClock, getAbsTime,
|
|
19
|
+
StaticPeriod) # pylint: disable=W0611
|
|
20
|
+
|
|
21
|
+
# always safe to call rush, even if its not going to do anything for a
|
|
22
|
+
# particular OS
|
|
23
|
+
from psychopy.platform_specific import rush # pylint: disable=W0611
|
|
24
|
+
from psychopy import logging
|
|
25
|
+
<<<<<<< HEAD
|
|
26
|
+
from psychopy.constants import STARTED, NOT_STARTED, FINISHED
|
|
27
|
+
=======
|
|
28
|
+
from psychopy.constants import STARTED, NOT_STARTED, FINISHED, PY3
|
|
29
|
+
from psychopy.iohub.client import ioHubConnection
|
|
30
|
+
>>>>>>> c06fff3cf5e2f418f6db297fd47819041a00c07d
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
import pyglet
|
|
34
|
+
havePyglet = True
|
|
35
|
+
# may not want to check, to preserve terminal window focus
|
|
36
|
+
checkPygletDuringWait = True
|
|
37
|
+
except ImportError:
|
|
38
|
+
havePyglet = False
|
|
39
|
+
checkPygletDuringWait = False
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
import glfw
|
|
43
|
+
haveGLFW = True
|
|
44
|
+
except ImportError:
|
|
45
|
+
haveGLFW = False
|
|
46
|
+
|
|
47
|
+
runningThreads = [] # just for backwards compatibility?
|
|
48
|
+
openWindows = [] # visual.Window updates this, event.py and clock.py use it
|
|
49
|
+
|
|
50
|
+
# Set getTime in core to == the monotonicClock instance created in the
|
|
51
|
+
# clockModule.
|
|
52
|
+
# The logging module sets the defaultClock to == clock.monotonicClock,
|
|
53
|
+
# so by default the core.getTime() and logging.defaultClock.getTime()
|
|
54
|
+
# functions return the 'same' timebase.
|
|
55
|
+
#
|
|
56
|
+
# This way 'all' OSs have a core.getTime() timebase that starts at 0.0 when
|
|
57
|
+
# the experiment is launched, instead of it being this way on Windows only
|
|
58
|
+
# (which was also a descripancy between OS's when win32 was using time.clock).
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def getTime(applyZero = True):
|
|
62
|
+
"""Get the current time since psychopy.core was loaded.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Version Notes: Note that prior to PsychoPy 1.77.00 the behaviour of
|
|
67
|
+
getTime() was platform dependent (on OSX and linux it was equivalent to
|
|
68
|
+
:func:`psychopy.core.getAbsTime`
|
|
69
|
+
whereas on windows it returned time since loading of the module, as now)
|
|
70
|
+
"""
|
|
71
|
+
return monotonicClock.getTime(applyZero)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def quit():
|
|
75
|
+
"""Close everything and exit nicely (ending the experiment)
|
|
76
|
+
"""
|
|
77
|
+
# pygame.quit() # safe even if pygame was never initialised
|
|
78
|
+
logging.flush()
|
|
79
|
+
|
|
80
|
+
# properly shutdown ioHub server
|
|
81
|
+
if ioHubConnection.ACTIVE_CONNECTION:
|
|
82
|
+
ioHubConnection.ACTIVE_CONNECTION.quit()
|
|
83
|
+
|
|
84
|
+
for thisThread in threading.enumerate():
|
|
85
|
+
if hasattr(thisThread, 'stop') and hasattr(thisThread, 'running'):
|
|
86
|
+
# this is one of our event threads - kill it and wait for success
|
|
87
|
+
thisThread.stop()
|
|
88
|
+
while thisThread.running == 0:
|
|
89
|
+
pass # wait until it has properly finished polling
|
|
90
|
+
|
|
91
|
+
sys.exit(0) # quits the python session entirely
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def shellCall(shellCmd, stdin='', stderr=False, env=None, encoding=None):
|
|
95
|
+
"""Call a single system command with arguments, return its stdout.
|
|
96
|
+
Returns stdout, stderr if stderr is True.
|
|
97
|
+
Handles simple pipes, passing stdin to shellCmd (pipes are untested
|
|
98
|
+
on windows) can accept string or list as the first argument
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
shellCmd : str, or iterable
|
|
103
|
+
The command to execute, and its respective arguments.
|
|
104
|
+
|
|
105
|
+
stdin : str, or None
|
|
106
|
+
Input to pass to the command.
|
|
107
|
+
|
|
108
|
+
stderr : bool
|
|
109
|
+
Whether to return the standard error output once execution is finished.
|
|
110
|
+
|
|
111
|
+
env : dict
|
|
112
|
+
The environment variables to set during execution.
|
|
113
|
+
|
|
114
|
+
encoding : str
|
|
115
|
+
The encoding to use for communication with the executed command.
|
|
116
|
+
This argument will be ignored on Python 2.7.
|
|
117
|
+
|
|
118
|
+
Notes
|
|
119
|
+
-----
|
|
120
|
+
We use ``subprocess.Popen`` to execute the command and establish
|
|
121
|
+
`stdin` and `stdout` pipes.
|
|
122
|
+
Python 2.7 always opens the pipes in text mode; however,
|
|
123
|
+
Python 3 defaults to binary mode, unless an encoding is specified.
|
|
124
|
+
To unify pipe communication across Python 2 and 3, we now provide an
|
|
125
|
+
`encoding` parameter, enforcing `utf-8` text mode by default.
|
|
126
|
+
This parameter is present from Python 3.6 onwards; using an older
|
|
127
|
+
Python 3 version will raise an exception. The parameter will be ignored
|
|
128
|
+
when running Python 2.7.
|
|
129
|
+
|
|
130
|
+
"""
|
|
131
|
+
if encoding is None:
|
|
132
|
+
encoding = locale.getpreferredencoding()
|
|
133
|
+
|
|
134
|
+
if type(shellCmd) == str:
|
|
135
|
+
# safely split into cmd+list-of-args, no pipes here
|
|
136
|
+
shellCmdList = shlex.split(shellCmd)
|
|
137
|
+
elif type(shellCmd) == bytes:
|
|
138
|
+
# safely split into cmd+list-of-args, no pipes here
|
|
139
|
+
shellCmdList = shlex.split(shellCmd.decode('utf-8'))
|
|
140
|
+
elif type(shellCmd) in (list, tuple): # handles whitespace in filenames
|
|
141
|
+
shellCmdList = shellCmd
|
|
142
|
+
else:
|
|
143
|
+
msg = 'shellCmd requires a string or iterable.'
|
|
144
|
+
raise TypeError(msg)
|
|
145
|
+
|
|
146
|
+
cmdObjects = []
|
|
147
|
+
for obj in shellCmdList:
|
|
148
|
+
if type(obj) != bytes:
|
|
149
|
+
cmdObjects.append(obj)
|
|
150
|
+
else:
|
|
151
|
+
cmdObjects.append(obj.decode('utf-8'))
|
|
152
|
+
|
|
153
|
+
# the `encoding` parameter results in unicode coming back
|
|
154
|
+
if sys.version_info.minor >= 6:
|
|
155
|
+
proc = subprocess.Popen(cmdObjects, stdin=subprocess.PIPE,
|
|
156
|
+
stdout=subprocess.PIPE,
|
|
157
|
+
stderr=subprocess.PIPE,
|
|
158
|
+
encoding=encoding, env=env)
|
|
159
|
+
else:
|
|
160
|
+
msg = 'shellCall() requires Python 2.7, or 3.6 and newer.'
|
|
161
|
+
raise RuntimeError(msg)
|
|
162
|
+
|
|
163
|
+
stdoutData, stderrData = proc.communicate(stdin)
|
|
164
|
+
|
|
165
|
+
del proc
|
|
166
|
+
if stderr:
|
|
167
|
+
return stdoutData.strip(), stderrData.strip()
|
|
168
|
+
else:
|
|
169
|
+
return stdoutData.strip()
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
This experiment was created using PsychoPy3 Experiment Builder (v2022.2.0dev3),
|
|
5
|
+
on Thu May 26 17:00:03 2022
|
|
6
|
+
If you publish work using this script the most relevant publication is:
|
|
7
|
+
|
|
8
|
+
Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019)
|
|
9
|
+
PsychoPy2: Experiments in behavior made easy Behav Res 51: 195.
|
|
10
|
+
https://doi.org/10.3758/s13428-018-01193-y
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# --- Import packages ---
|
|
15
|
+
from psychopy import locale_setup
|
|
16
|
+
from psychopy import prefs
|
|
17
|
+
from psychopy import sound, gui, visual, core, data, event, logging, clock, colors, layout
|
|
18
|
+
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
|
|
19
|
+
STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
|
|
20
|
+
|
|
21
|
+
import numpy as np # whole numpy lib is available, prepend 'np.'
|
|
22
|
+
from numpy import (sin, cos, tan, log, log10, pi, average,
|
|
23
|
+
sqrt, std, deg2rad, rad2deg, linspace, asarray)
|
|
24
|
+
from numpy.random import random, randint, normal, shuffle, choice as randchoice
|
|
25
|
+
import os # handy system and path functions
|
|
26
|
+
import sys # to get file system encoding
|
|
27
|
+
|
|
28
|
+
import psychopy.iohub as io
|
|
29
|
+
from psychopy.hardware import keyboard
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Ensure that relative paths start from the same directory as this script
|
|
34
|
+
_thisDir = os.path.dirname(os.path.abspath(__file__))
|
|
35
|
+
os.chdir(_thisDir)
|
|
36
|
+
# Store info about the experiment session
|
|
37
|
+
psychopyVersion = '2022.2.0dev3'
|
|
38
|
+
expName = 'blockedTrials' # from the Builder filename that created this script
|
|
39
|
+
expInfo = {
|
|
40
|
+
'session': '001',
|
|
41
|
+
'participant': "subj%06.0f" %(random()*100000),
|
|
42
|
+
}
|
|
43
|
+
# --- Show participant info dialog --
|
|
44
|
+
dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
|
|
45
|
+
if dlg.OK == False:
|
|
46
|
+
core.quit() # user pressed cancel
|
|
47
|
+
expInfo['date'] = data.getDateStr() # add a simple timestamp
|
|
48
|
+
expInfo['expName'] = expName
|
|
49
|
+
expInfo['psychopyVersion'] = psychopyVersion
|
|
50
|
+
|
|
51
|
+
# Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
|
|
52
|
+
filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
|
|
53
|
+
|
|
54
|
+
# An ExperimentHandler isn't essential but helps with data saving
|
|
55
|
+
thisExp = data.ExperimentHandler(name=expName, version='',
|
|
56
|
+
extraInfo=expInfo, runtimeInfo=None,
|
|
57
|
+
originPath='psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py',
|
|
58
|
+
savePickle=True, saveWideText=True,
|
|
59
|
+
dataFileName=filename)
|
|
60
|
+
# save a log file for detail verbose info
|
|
61
|
+
logFile = logging.LogFile(filename+'.log', level=logging.EXP)
|
|
62
|
+
logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file
|
|
63
|
+
|
|
64
|
+
endExpNow = False # flag for 'escape' or other condition => quit the exp
|
|
65
|
+
frameTolerance = 0.001 # how close to onset before 'same' frame
|
|
66
|
+
|
|
67
|
+
# Start Code - component code to be run after the window creation
|
|
68
|
+
|
|
69
|
+
# --- Setup the Window ---
|
|
70
|
+
win = visual.Window(
|
|
71
|
+
size=[1440, 900], fullscr=True, screen=0,
|
|
72
|
+
winType='pyglet', allowGUI=False, allowStencil=False,
|
|
73
|
+
monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
|
|
74
|
+
blendMode='avg', useFBO=True,
|
|
75
|
+
units='height')
|
|
76
|
+
# store frame rate of monitor if we can measure it
|
|
77
|
+
expInfo['frameRate'] = win.getActualFrameRate()
|
|
78
|
+
if expInfo['frameRate'] != None:
|
|
79
|
+
frameDur = 1.0 / round(expInfo['frameRate'])
|
|
80
|
+
else:
|
|
81
|
+
frameDur = 1.0 / 60.0 # could not measure, so guess
|
|
82
|
+
# --- Setup input devices ---
|
|
83
|
+
ioConfig = {}
|
|
84
|
+
|
|
85
|
+
# Setup iohub keyboard
|
|
86
|
+
ioConfig['Keyboard'] = dict(use_keymap='psychopy')
|
|
87
|
+
|
|
88
|
+
ioSession = '1'
|
|
89
|
+
if 'session' in expInfo:
|
|
90
|
+
ioSession = str(expInfo['session'])
|
|
91
|
+
ioServer = io.launchHubServer(window=win, **ioConfig)
|
|
92
|
+
eyetracker = None
|
|
93
|
+
|
|
94
|
+
# create a default keyboard (e.g. to check for escape)
|
|
95
|
+
defaultKeyboard = keyboard.Keyboard(backend='iohub')
|
|
96
|
+
|
|
97
|
+
# --- Initialize components for Routine "readyMessage" ---
|
|
98
|
+
readyMessageClock = core.Clock()
|
|
99
|
+
textbox = visual.TextBox2(
|
|
100
|
+
win, text='', font='Open Sans',
|
|
101
|
+
pos=(0, 0), letterHeight=0.05,
|
|
102
|
+
size=(0.4, 0.4), borderWidth=2.0,
|
|
103
|
+
color='white', colorSpace='rgb',
|
|
104
|
+
opacity=1.0,
|
|
105
|
+
bold=False, italic=False,
|
|
106
|
+
lineSpacing=1.0,
|
|
107
|
+
padding=None, alignment='center',
|
|
108
|
+
anchor='center',
|
|
109
|
+
fillColor=None, borderColor=None,
|
|
110
|
+
flipHoriz=False, flipVert=False, languageStyle='LTR',
|
|
111
|
+
editable=False,
|
|
112
|
+
name='textbox',
|
|
113
|
+
autoLog=True,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# --- Initialize components for Routine "trial" ---
|
|
117
|
+
trialClock = core.Clock()
|
|
118
|
+
image = visual.ImageStim(
|
|
119
|
+
win=win,
|
|
120
|
+
name='image', units='height',
|
|
121
|
+
image='sin', mask=None, anchor='center',
|
|
122
|
+
ori=0, pos=(0, 0), size=(0.5,0.5),
|
|
123
|
+
color=[1,1,1], colorSpace='rgb', opacity=1,
|
|
124
|
+
flipHoriz=False, flipVert=False,
|
|
125
|
+
texRes=128, interpolate=True, depth=0.0)
|
|
126
|
+
|
|
127
|
+
# Create some handy timers
|
|
128
|
+
globalClock = core.Clock() # to track the time since experiment started
|
|
129
|
+
routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine
|
|
130
|
+
|
|
131
|
+
# set up handler to look after randomisation of conditions etc
|
|
132
|
+
blocks = data.TrialHandler(nReps=2, method='random',
|
|
133
|
+
extraInfo=expInfo, originPath=-1,
|
|
134
|
+
trialList=data.importConditions('chooseBlock.xlsx'),
|
|
135
|
+
seed=None, name='blocks')
|
|
136
|
+
thisExp.addLoop(blocks) # add the loop to the experiment
|
|
137
|
+
thisBlock = blocks.trialList[0] # so we can initialise stimuli with some values
|
|
138
|
+
# abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
|
|
139
|
+
if thisBlock != None:
|
|
140
|
+
for paramName in thisBlock:
|
|
141
|
+
exec('{} = thisBlock[paramName]'.format(paramName))
|
|
142
|
+
|
|
143
|
+
for thisBlock in blocks:
|
|
144
|
+
currentLoop = blocks
|
|
145
|
+
# abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
|
|
146
|
+
if thisBlock != None:
|
|
147
|
+
for paramName in thisBlock:
|
|
148
|
+
exec('{} = thisBlock[paramName]'.format(paramName))
|
|
149
|
+
|
|
150
|
+
# --- Prepare to start Routine "readyMessage" ---
|
|
151
|
+
continueRoutine = True
|
|
152
|
+
routineTimer.add(1.000000)
|
|
153
|
+
# update component parameters for each repeat
|
|
154
|
+
textbox.reset()
|
|
155
|
+
textbox.setText(readyMsg)
|
|
156
|
+
# keep track of which components have finished
|
|
157
|
+
readyMessageComponents = [textbox]
|
|
158
|
+
for thisComponent in readyMessageComponents:
|
|
159
|
+
thisComponent.tStart = None
|
|
160
|
+
thisComponent.tStop = None
|
|
161
|
+
thisComponent.tStartRefresh = None
|
|
162
|
+
thisComponent.tStopRefresh = None
|
|
163
|
+
if hasattr(thisComponent, 'status'):
|
|
164
|
+
thisComponent.status = NOT_STARTED
|
|
165
|
+
# reset timers
|
|
166
|
+
t = 0
|
|
167
|
+
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
|
|
168
|
+
readyMessageClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
|
|
169
|
+
frameN = -1
|
|
170
|
+
|
|
171
|
+
# --- Run Routine "readyMessage" ---
|
|
172
|
+
while continueRoutine and routineTimer.getTime() > 0:
|
|
173
|
+
# get current time
|
|
174
|
+
t = readyMessageClock.getTime()
|
|
175
|
+
tThisFlip = win.getFutureFlipTime(clock=readyMessageClock)
|
|
176
|
+
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
|
|
177
|
+
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
|
|
178
|
+
# update/draw components on each frame
|
|
179
|
+
|
|
180
|
+
# *textbox* updates
|
|
181
|
+
if textbox.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
|
|
182
|
+
# keep track of start time/frame for later
|
|
183
|
+
textbox.frameNStart = frameN # exact frame index
|
|
184
|
+
textbox.tStart = t # local t and not account for scr refresh
|
|
185
|
+
textbox.tStartRefresh = tThisFlipGlobal # on global time
|
|
186
|
+
win.timeOnFlip(textbox, 'tStartRefresh') # time at next scr refresh
|
|
187
|
+
textbox.setAutoDraw(True)
|
|
188
|
+
if textbox.status == STARTED:
|
|
189
|
+
# is it time to stop? (based on global clock, using actual start)
|
|
190
|
+
if tThisFlipGlobal > textbox.tStartRefresh + 1.0-frameTolerance:
|
|
191
|
+
# keep track of stop time/frame for later
|
|
192
|
+
textbox.tStop = t # not accounting for scr refresh
|
|
193
|
+
textbox.frameNStop = frameN # exact frame index
|
|
194
|
+
win.timeOnFlip(textbox, 'tStopRefresh') # time at next scr refresh
|
|
195
|
+
textbox.setAutoDraw(False)
|
|
196
|
+
|
|
197
|
+
# check for quit (typically the Esc key)
|
|
198
|
+
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
|
|
199
|
+
core.quit()
|
|
200
|
+
|
|
201
|
+
# check if all components have finished
|
|
202
|
+
if not continueRoutine: # a component has requested a forced-end of Routine
|
|
203
|
+
break
|
|
204
|
+
continueRoutine = False # will revert to True if at least one component still running
|
|
205
|
+
for thisComponent in readyMessageComponents:
|
|
206
|
+
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
|
|
207
|
+
continueRoutine = True
|
|
208
|
+
break # at least one component has not yet finished
|
|
209
|
+
|
|
210
|
+
# refresh the screen
|
|
211
|
+
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
|
|
212
|
+
win.flip()
|
|
213
|
+
|
|
214
|
+
# --- Ending Routine "readyMessage" ---
|
|
215
|
+
for thisComponent in readyMessageComponents:
|
|
216
|
+
if hasattr(thisComponent, "setAutoDraw"):
|
|
217
|
+
thisComponent.setAutoDraw(False)
|
|
218
|
+
blocks.addData('textbox.started', textbox.tStartRefresh)
|
|
219
|
+
blocks.addData('textbox.stopped', textbox.tStopRefresh)
|
|
220
|
+
|
|
221
|
+
# set up handler to look after randomisation of conditions etc
|
|
222
|
+
trials = data.TrialHandler(nReps=1, method='random',
|
|
223
|
+
extraInfo=expInfo, originPath=-1,
|
|
224
|
+
trialList=data.importConditions(condsFile),
|
|
225
|
+
seed=None, name='trials')
|
|
226
|
+
thisExp.addLoop(trials) # add the loop to the experiment
|
|
227
|
+
thisTrial = trials.trialList[0] # so we can initialise stimuli with some values
|
|
228
|
+
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
|
|
229
|
+
if thisTrial != None:
|
|
230
|
+
for paramName in thisTrial:
|
|
231
|
+
exec('{} = thisTrial[paramName]'.format(paramName))
|
|
232
|
+
|
|
233
|
+
for thisTrial in trials:
|
|
234
|
+
currentLoop = trials
|
|
235
|
+
# abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
|
|
236
|
+
if thisTrial != None:
|
|
237
|
+
for paramName in thisTrial:
|
|
238
|
+
exec('{} = thisTrial[paramName]'.format(paramName))
|
|
239
|
+
|
|
240
|
+
# --- Prepare to start Routine "trial" ---
|
|
241
|
+
continueRoutine = True
|
|
242
|
+
routineTimer.add(1.500000)
|
|
243
|
+
# update component parameters for each repeat
|
|
244
|
+
image.setImage(stimFile)
|
|
245
|
+
# keep track of which components have finished
|
|
246
|
+
trialComponents = [image]
|
|
247
|
+
for thisComponent in trialComponents:
|
|
248
|
+
thisComponent.tStart = None
|
|
249
|
+
thisComponent.tStop = None
|
|
250
|
+
thisComponent.tStartRefresh = None
|
|
251
|
+
thisComponent.tStopRefresh = None
|
|
252
|
+
if hasattr(thisComponent, 'status'):
|
|
253
|
+
thisComponent.status = NOT_STARTED
|
|
254
|
+
# reset timers
|
|
255
|
+
t = 0
|
|
256
|
+
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
|
|
257
|
+
trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
|
|
258
|
+
frameN = -1
|
|
259
|
+
|
|
260
|
+
# --- Run Routine "trial" ---
|
|
261
|
+
while continueRoutine and routineTimer.getTime() > 0:
|
|
262
|
+
# get current time
|
|
263
|
+
t = trialClock.getTime()
|
|
264
|
+
tThisFlip = win.getFutureFlipTime(clock=trialClock)
|
|
265
|
+
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
|
|
266
|
+
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
|
|
267
|
+
# update/draw components on each frame
|
|
268
|
+
|
|
269
|
+
# *image* updates
|
|
270
|
+
if image.status == NOT_STARTED and tThisFlip >= 0.5-frameTolerance:
|
|
271
|
+
# keep track of start time/frame for later
|
|
272
|
+
image.frameNStart = frameN # exact frame index
|
|
273
|
+
image.tStart = t # local t and not account for scr refresh
|
|
274
|
+
image.tStartRefresh = tThisFlipGlobal # on global time
|
|
275
|
+
win.timeOnFlip(image, 'tStartRefresh') # time at next scr refresh
|
|
276
|
+
image.setAutoDraw(True)
|
|
277
|
+
if image.status == STARTED:
|
|
278
|
+
# is it time to stop? (based on global clock, using actual start)
|
|
279
|
+
if tThisFlipGlobal > image.tStartRefresh + 1.0-frameTolerance:
|
|
280
|
+
# keep track of stop time/frame for later
|
|
281
|
+
image.tStop = t # not accounting for scr refresh
|
|
282
|
+
image.frameNStop = frameN # exact frame index
|
|
283
|
+
win.timeOnFlip(image, 'tStopRefresh') # time at next scr refresh
|
|
284
|
+
image.setAutoDraw(False)
|
|
285
|
+
|
|
286
|
+
# check for quit (typically the Esc key)
|
|
287
|
+
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
|
|
288
|
+
core.quit()
|
|
289
|
+
|
|
290
|
+
# check if all components have finished
|
|
291
|
+
if not continueRoutine: # a component has requested a forced-end of Routine
|
|
292
|
+
break
|
|
293
|
+
continueRoutine = False # will revert to True if at least one component still running
|
|
294
|
+
for thisComponent in trialComponents:
|
|
295
|
+
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
|
|
296
|
+
continueRoutine = True
|
|
297
|
+
break # at least one component has not yet finished
|
|
298
|
+
|
|
299
|
+
# refresh the screen
|
|
300
|
+
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
|
|
301
|
+
win.flip()
|
|
302
|
+
|
|
303
|
+
# --- Ending Routine "trial" ---
|
|
304
|
+
for thisComponent in trialComponents:
|
|
305
|
+
if hasattr(thisComponent, "setAutoDraw"):
|
|
306
|
+
thisComponent.setAutoDraw(False)
|
|
307
|
+
trials.addData('image.started', image.tStartRefresh)
|
|
308
|
+
trials.addData('image.stopped', image.tStopRefresh)
|
|
309
|
+
thisExp.nextEntry()
|
|
310
|
+
|
|
311
|
+
# completed 1 repeats of 'trials'
|
|
312
|
+
|
|
313
|
+
# completed 2 repeats of 'blocks'
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
# --- End experiment ---
|
|
317
|
+
# Flip one final time so any remaining win.callOnFlip()
|
|
318
|
+
# and win.timeOnFlip() tasks get executed before quitting
|
|
319
|
+
win.flip()
|
|
320
|
+
|
|
321
|
+
# these shouldn't be strictly necessary (should auto-save)
|
|
322
|
+
thisExp.saveAsWideText(filename+'.csv', delim='auto')
|
|
323
|
+
thisExp.saveAsPickle(filename)
|
|
324
|
+
logging.flush()
|
|
325
|
+
# make sure everything is closed down
|
|
326
|
+
if eyetracker:
|
|
327
|
+
eyetracker.setConnectionState(False)
|
|
328
|
+
thisExp.abort() # or data files will save again on exit
|
|
329
|
+
win.close()
|
|
330
|
+
core.quit()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|