psychopy 2025.2.4__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.
- psychopy/CHANGELOG.txt +3981 -0
- psychopy/GIT_SHA +1 -0
- psychopy/LICENSE.txt +11 -0
- psychopy/LICENSES.txt +55 -0
- psychopy/VERSION +1 -0
- psychopy/__init__.py +148 -0
- psychopy/alerts/__init__.py +65 -0
- psychopy/alerts/_alerts.py +224 -0
- psychopy/alerts/_errorHandler.py +50 -0
- psychopy/alerts/alertsCatalogue/1000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/1100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/1500.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2110.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2115.yaml +21 -0
- psychopy/alerts/alertsCatalogue/2120.yaml +22 -0
- psychopy/alerts/alertsCatalogue/2150.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2155.yaml +21 -0
- psychopy/alerts/alertsCatalogue/2300.yaml +0 -0
- psychopy/alerts/alertsCatalogue/2500.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3110.yaml +25 -0
- psychopy/alerts/alertsCatalogue/3115.yaml +24 -0
- psychopy/alerts/alertsCatalogue/3200.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
- psychopy/alerts/alertsCatalogue/3400.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3600.yaml +0 -0
- psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/4051.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4052.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4100.yaml +0 -0
- psychopy/alerts/alertsCatalogue/4105.yaml +18 -0
- psychopy/alerts/alertsCatalogue/4115.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4120.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4125.yaml +23 -0
- psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4160.yaml +25 -0
- psychopy/alerts/alertsCatalogue/4200.yaml +0 -0
- psychopy/alerts/alertsCatalogue/4205.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4210.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4305.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4310.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4315.yaml +21 -0
- psychopy/alerts/alertsCatalogue/4320.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4325.yaml +23 -0
- psychopy/alerts/alertsCatalogue/4330.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4335.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4340.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4405.yaml +24 -0
- psychopy/alerts/alertsCatalogue/4505.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4510.yaml +25 -0
- psychopy/alerts/alertsCatalogue/4520.yaml +26 -0
- psychopy/alerts/alertsCatalogue/4530.yaml +23 -0
- psychopy/alerts/alertsCatalogue/4540.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4545.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4550.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4605.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4610.yaml +22 -0
- psychopy/alerts/alertsCatalogue/4615.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4705.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4710.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4810.yaml +19 -0
- psychopy/alerts/alertsCatalogue/5000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/5055.yaml +25 -0
- psychopy/alerts/alertsCatalogue/6000.yaml +0 -0
- psychopy/alerts/alertsCatalogue/6105.yaml +18 -0
- psychopy/alerts/alertsCatalogue/7105.yaml +19 -0
- psychopy/alerts/alertsCatalogue/8105.yaml +21 -0
- psychopy/alerts/alertsCatalogue/8110.yaml +21 -0
- psychopy/alerts/alertsCatalogue/9998.yaml +19 -0
- psychopy/alerts/alertsCatalogue/9999.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +123 -0
- psychopy/alerts/alertsCatalogue/alertTemplate.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertmsg.py +173 -0
- psychopy/alerts/alertsCatalogue/generateAlertmsg.py +34 -0
- psychopy/alerts/alerttools.py +322 -0
- psychopy/app/Resources/README.md +12 -0
- psychopy/app/Resources/__init__.py +0 -0
- psychopy/app/Resources/betasplash.png +0 -0
- psychopy/app/Resources/betasplash@2x.png +0 -0
- psychopy/app/Resources/builder.ico +0 -0
- psychopy/app/Resources/classic/FlowBottom_CompLeft.png +0 -0
- psychopy/app/Resources/classic/FlowBottom_CompRight.png +0 -0
- psychopy/app/Resources/classic/FlowTop_CompLeft.png +0 -0
- psychopy/app/Resources/classic/FlowTop_CompRight.png +0 -0
- psychopy/app/Resources/classic/README.txt +9 -0
- psychopy/app/Resources/classic/__init__.py +0 -0
- psychopy/app/Resources/classic/_layouts.ai +1138 -1
- psychopy/app/Resources/classic/add.png +0 -0
- psychopy/app/Resources/classic/add@2x.png +0 -0
- psychopy/app/Resources/classic/addExp32.png +0 -0
- psychopy/app/Resources/classic/add_many.png +0 -0
- psychopy/app/Resources/classic/add_many@2x.png +0 -0
- psychopy/app/Resources/classic/alerts.png +0 -0
- psychopy/app/Resources/classic/beta.png +0 -0
- psychopy/app/Resources/classic/browser.png +0 -0
- psychopy/app/Resources/classic/browser@2x.png +0 -0
- psychopy/app/Resources/classic/bug16.png +0 -0
- psychopy/app/Resources/classic/case.png +0 -0
- psychopy/app/Resources/classic/case@2x.png +0 -0
- psychopy/app/Resources/classic/circle_mask.png +0 -0
- psychopy/app/Resources/classic/circle_mask@2x.png +0 -0
- psychopy/app/Resources/classic/clear.png +0 -0
- psychopy/app/Resources/classic/clear@2x.png +0 -0
- psychopy/app/Resources/classic/coderclass16.png +0 -0
- psychopy/app/Resources/classic/coderfunc16.png +0 -0
- psychopy/app/Resources/classic/coderimport16.png +0 -0
- psychopy/app/Resources/classic/coderjs16.png +0 -0
- psychopy/app/Resources/classic/coderpython16.png +0 -0
- psychopy/app/Resources/classic/codervar16.png +0 -0
- psychopy/app/Resources/classic/cogwindow32.png +0 -0
- psychopy/app/Resources/classic/color32.png +0 -0
- psychopy/app/Resources/classic/compile32.png +0 -0
- psychopy/app/Resources/classic/compile_js.png +0 -0
- psychopy/app/Resources/classic/compile_js@2x.png +0 -0
- psychopy/app/Resources/classic/compile_py.png +0 -0
- psychopy/app/Resources/classic/compile_py@2x.png +0 -0
- psychopy/app/Resources/classic/copy16.png +0 -0
- psychopy/app/Resources/classic/currentFile.png +0 -0
- psychopy/app/Resources/classic/currentFile@2x.png +0 -0
- psychopy/app/Resources/classic/delete16.png +0 -0
- psychopy/app/Resources/classic/desktop.png +0 -0
- psychopy/app/Resources/classic/desktop@2x.png +0 -0
- psychopy/app/Resources/classic/devices.png +0 -0
- psychopy/app/Resources/classic/devices@2x.png +0 -0
- psychopy/app/Resources/classic/dirup16.png +0 -0
- psychopy/app/Resources/classic/docclose16.png +0 -0
- psychopy/app/Resources/classic/download.png +0 -0
- psychopy/app/Resources/classic/edit.png +0 -0
- psychopy/app/Resources/classic/edit@2x.png +0 -0
- psychopy/app/Resources/classic/editbtn.png +0 -0
- psychopy/app/Resources/classic/editbtn16.png +0 -0
- psychopy/app/Resources/classic/editbtn16@2x.png +0 -0
- psychopy/app/Resources/classic/editbtn@2x.png +0 -0
- psychopy/app/Resources/classic/email.png +0 -0
- psychopy/app/Resources/classic/email@2x.png +0 -0
- psychopy/app/Resources/classic/experiment.png +0 -0
- psychopy/app/Resources/classic/experiment@2x.png +0 -0
- psychopy/app/Resources/classic/expsettings.png +0 -0
- psychopy/app/Resources/classic/expsettings@2x.png +0 -0
- psychopy/app/Resources/classic/file.png +0 -0
- psychopy/app/Resources/classic/file@2x.png +0 -0
- psychopy/app/Resources/classic/fileaudio.png +0 -0
- psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
- psychopy/app/Resources/classic/filecss.png +0 -0
- psychopy/app/Resources/classic/filecss@2x.png +0 -0
- psychopy/app/Resources/classic/filecsv.png +0 -0
- psychopy/app/Resources/classic/filecsv@2x.png +0 -0
- psychopy/app/Resources/classic/filedesign.png +0 -0
- psychopy/app/Resources/classic/filedesign@2x.png +0 -0
- psychopy/app/Resources/classic/filefont.png +0 -0
- psychopy/app/Resources/classic/filefont@2x.png +0 -0
- psychopy/app/Resources/classic/filegit.png +0 -0
- psychopy/app/Resources/classic/filegit@2x.png +0 -0
- psychopy/app/Resources/classic/filehtml.png +0 -0
- psychopy/app/Resources/classic/filehtml@2x.png +0 -0
- psychopy/app/Resources/classic/fileimage.png +0 -0
- psychopy/app/Resources/classic/fileimage@2x.png +0 -0
- psychopy/app/Resources/classic/fileinfo.png +0 -0
- psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
- psychopy/app/Resources/classic/filejs.png +0 -0
- psychopy/app/Resources/classic/filejs@2x.png +0 -0
- psychopy/app/Resources/classic/filejson.png +0 -0
- psychopy/app/Resources/classic/filejson@2x.png +0 -0
- psychopy/app/Resources/classic/filenew.png +0 -0
- psychopy/app/Resources/classic/filenew32.png +0 -0
- psychopy/app/Resources/classic/filenew@2x.png +0 -0
- psychopy/app/Resources/classic/fileopen.png +0 -0
- psychopy/app/Resources/classic/fileopen32.png +0 -0
- psychopy/app/Resources/classic/fileopen@2x.png +0 -0
- psychopy/app/Resources/classic/filepkg.png +0 -0
- psychopy/app/Resources/classic/filepkg@2x.png +0 -0
- psychopy/app/Resources/classic/filepsyexp.png +0 -0
- psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/classic/filepy.png +0 -0
- psychopy/app/Resources/classic/filepy@2x.png +0 -0
- psychopy/app/Resources/classic/filesave.png +0 -0
- psychopy/app/Resources/classic/filesave32.png +0 -0
- psychopy/app/Resources/classic/filesave@2x.png +0 -0
- psychopy/app/Resources/classic/filesaveas.png +0 -0
- psychopy/app/Resources/classic/filesaveas32.png +0 -0
- psychopy/app/Resources/classic/filesaveas@2x.png +0 -0
- psychopy/app/Resources/classic/filetxt.png +0 -0
- psychopy/app/Resources/classic/filetxt@2x.png +0 -0
- psychopy/app/Resources/classic/fileunknown.png +0 -0
- psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
- psychopy/app/Resources/classic/filevideo.png +0 -0
- psychopy/app/Resources/classic/filevideo@2x.png +0 -0
- psychopy/app/Resources/classic/filter.png +0 -0
- psychopy/app/Resources/classic/filter@2x.png +0 -0
- psychopy/app/Resources/classic/find.png +0 -0
- psychopy/app/Resources/classic/find@2x.png +0 -0
- psychopy/app/Resources/classic/folder-open16.png +0 -0
- psychopy/app/Resources/classic/folder16.png +0 -0
- psychopy/app/Resources/classic/foldernew16.png +0 -0
- psychopy/app/Resources/classic/fork.png +0 -0
- psychopy/app/Resources/classic/fork@2x.png +0 -0
- psychopy/app/Resources/classic/github.png +0 -0
- psychopy/app/Resources/classic/github@2x.png +0 -0
- psychopy/app/Resources/classic/globe.png +0 -0
- psychopy/app/Resources/classic/globe@2x.png +0 -0
- psychopy/app/Resources/classic/globe_bug.png +0 -0
- psychopy/app/Resources/classic/globe_bug@2x.png +0 -0
- psychopy/app/Resources/classic/globe_greensync.png +0 -0
- psychopy/app/Resources/classic/globe_greensync@2x.png +0 -0
- psychopy/app/Resources/classic/globe_info.png +0 -0
- psychopy/app/Resources/classic/globe_info@2x.png +0 -0
- psychopy/app/Resources/classic/globe_magnifier.png +0 -0
- psychopy/app/Resources/classic/globe_magnifier@2x.png +0 -0
- psychopy/app/Resources/classic/globe_run.png +0 -0
- psychopy/app/Resources/classic/globe_run@2x.png +0 -0
- psychopy/app/Resources/classic/globe_user.png +0 -0
- psychopy/app/Resources/classic/globe_user@2x.png +0 -0
- psychopy/app/Resources/classic/goto16.png +0 -0
- psychopy/app/Resources/classic/greendot.png +0 -0
- psychopy/app/Resources/classic/greendot@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe.png +0 -0
- psychopy/app/Resources/classic/greenglobe@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_bug.png +0 -0
- psychopy/app/Resources/classic/greenglobe_bug@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_greensync.png +0 -0
- psychopy/app/Resources/classic/greenglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_info.png +0 -0
- psychopy/app/Resources/classic/greenglobe_info@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_magnifier.png +0 -0
- psychopy/app/Resources/classic/greenglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_run.png +0 -0
- psychopy/app/Resources/classic/greenglobe_run@2x.png +0 -0
- psychopy/app/Resources/classic/greenglobe_user.png +0 -0
- psychopy/app/Resources/classic/greenglobe_user@2x.png +0 -0
- psychopy/app/Resources/classic/greydot.png +0 -0
- psychopy/app/Resources/classic/greydot@2x.png +0 -0
- psychopy/app/Resources/classic/greytick.png +0 -0
- psychopy/app/Resources/classic/greytick@2x.png +0 -0
- psychopy/app/Resources/classic/invalid_img.png +0 -0
- psychopy/app/Resources/classic/jsPilot.png +0 -0
- psychopy/app/Resources/classic/jsPilot@2x.png +0 -0
- psychopy/app/Resources/classic/jsRun.png +0 -0
- psychopy/app/Resources/classic/jsRun@2x.png +0 -0
- psychopy/app/Resources/classic/libroot.png +0 -0
- psychopy/app/Resources/classic/libroot@2x.png +0 -0
- psychopy/app/Resources/classic/loop.png +0 -0
- psychopy/app/Resources/classic/loop@2x.png +0 -0
- psychopy/app/Resources/classic/monitor16.png +0 -0
- psychopy/app/Resources/classic/monitors.png +0 -0
- psychopy/app/Resources/classic/monitors16.png +0 -0
- psychopy/app/Resources/classic/monitors32.png +0 -0
- psychopy/app/Resources/classic/monitors@2x.png +0 -0
- psychopy/app/Resources/classic/orangedot.png +0 -0
- psychopy/app/Resources/classic/orangedot@2x.png +0 -0
- psychopy/app/Resources/classic/pavlovia.png +0 -0
- psychopy/app/Resources/classic/pavlovia16.png +0 -0
- psychopy/app/Resources/classic/pavlovia16@2x.png +0 -0
- psychopy/app/Resources/classic/pavlovia@2x.png +0 -0
- psychopy/app/Resources/classic/pavsync.png +0 -0
- psychopy/app/Resources/classic/pavsync@2x.png +0 -0
- psychopy/app/Resources/classic/person_off.png +0 -0
- psychopy/app/Resources/classic/person_off@2x.png +0 -0
- psychopy/app/Resources/classic/person_on.png +0 -0
- psychopy/app/Resources/classic/person_on@2x.png +0 -0
- psychopy/app/Resources/classic/photometer.png +0 -0
- psychopy/app/Resources/classic/photometer@2x.png +0 -0
- psychopy/app/Resources/classic/plugin16.png +0 -0
- psychopy/app/Resources/classic/plugin16@2x.png +0 -0
- psychopy/app/Resources/classic/plugins32.png +0 -0
- psychopy/app/Resources/classic/plus.png +0 -0
- psychopy/app/Resources/classic/plus@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-app.png +0 -0
- psychopy/app/Resources/classic/preferences-app48.png +0 -0
- psychopy/app/Resources/classic/preferences-app@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-conn.png +0 -0
- psychopy/app/Resources/classic/preferences-conn48.png +0 -0
- psychopy/app/Resources/classic/preferences-conn@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-debug.png +0 -0
- psychopy/app/Resources/classic/preferences-debug@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-general.png +0 -0
- psychopy/app/Resources/classic/preferences-general48.png +0 -0
- psychopy/app/Resources/classic/preferences-general@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-hardware.png +0 -0
- psychopy/app/Resources/classic/preferences-hardware48.png +0 -0
- psychopy/app/Resources/classic/preferences-hardware@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-keyboard.png +0 -0
- psychopy/app/Resources/classic/preferences-keyboard48.png +0 -0
- psychopy/app/Resources/classic/preferences-keyboard@2x.png +0 -0
- psychopy/app/Resources/classic/preferences-pilot.png +0 -0
- psychopy/app/Resources/classic/preferences-pilot@2x.png +0 -0
- psychopy/app/Resources/classic/preferences32.png +0 -0
- psychopy/app/Resources/classic/pyPilot.png +0 -0
- psychopy/app/Resources/classic/pyPilot@2x.png +0 -0
- psychopy/app/Resources/classic/pyRun.png +0 -0
- psychopy/app/Resources/classic/pyRun@2x.png +0 -0
- psychopy/app/Resources/classic/reddot.png +0 -0
- psychopy/app/Resources/classic/reddot@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe.png +0 -0
- psychopy/app/Resources/classic/redglobe@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_bug.png +0 -0
- psychopy/app/Resources/classic/redglobe_bug@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_greensync.png +0 -0
- psychopy/app/Resources/classic/redglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_info.png +0 -0
- psychopy/app/Resources/classic/redglobe_info@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_magnifier.png +0 -0
- psychopy/app/Resources/classic/redglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_run.png +0 -0
- psychopy/app/Resources/classic/redglobe_run@2x.png +0 -0
- psychopy/app/Resources/classic/redglobe_user.png +0 -0
- psychopy/app/Resources/classic/redglobe_user@2x.png +0 -0
- psychopy/app/Resources/classic/redo.png +0 -0
- psychopy/app/Resources/classic/redo32.png +0 -0
- psychopy/app/Resources/classic/redo@2x.png +0 -0
- psychopy/app/Resources/classic/regex.png +0 -0
- psychopy/app/Resources/classic/regex@2x.png +0 -0
- psychopy/app/Resources/classic/removeExp32.png +0 -0
- psychopy/app/Resources/classic/rename16.png +0 -0
- psychopy/app/Resources/classic/restart.png +0 -0
- psychopy/app/Resources/classic/restart@2x.png +0 -0
- psychopy/app/Resources/classic/run.png +0 -0
- psychopy/app/Resources/classic/run@2x.png +0 -0
- psychopy/app/Resources/classic/runner.png +0 -0
- psychopy/app/Resources/classic/runner@2x.png +0 -0
- psychopy/app/Resources/classic/runnerPilot.png +0 -0
- psychopy/app/Resources/classic/runnerPilot@2x.png +0 -0
- psychopy/app/Resources/classic/savebtn.png +0 -0
- psychopy/app/Resources/classic/savebtn16.png +0 -0
- psychopy/app/Resources/classic/savebtn16@2x.png +0 -0
- psychopy/app/Resources/classic/savebtn@2x.png +0 -0
- psychopy/app/Resources/classic/search.png +0 -0
- psychopy/app/Resources/classic/search@2x.png +0 -0
- psychopy/app/Resources/classic/showBuilder.png +0 -0
- psychopy/app/Resources/classic/showBuilder@2x.png +0 -0
- psychopy/app/Resources/classic/showCoder.png +0 -0
- psychopy/app/Resources/classic/showCoder@2x.png +0 -0
- psychopy/app/Resources/classic/showRunner.png +0 -0
- psychopy/app/Resources/classic/showRunner@2x.png +0 -0
- psychopy/app/Resources/classic/starred.png +0 -0
- psychopy/app/Resources/classic/starred@2x.png +0 -0
- psychopy/app/Resources/classic/start.png +0 -0
- psychopy/app/Resources/classic/start@2x.png +0 -0
- psychopy/app/Resources/classic/stdout.png +0 -0
- psychopy/app/Resources/classic/stop.png +0 -0
- psychopy/app/Resources/classic/stop32.png +0 -0
- psychopy/app/Resources/classic/stop@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlBot.png +0 -0
- psychopy/app/Resources/classic/switchCtrlBot@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlLeft.png +0 -0
- psychopy/app/Resources/classic/switchCtrlLeft@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlRight.png +0 -0
- psychopy/app/Resources/classic/switchCtrlRight@2x.png +0 -0
- psychopy/app/Resources/classic/switchCtrlTop.png +0 -0
- psychopy/app/Resources/classic/switchCtrlTop@2x.png +0 -0
- psychopy/app/Resources/classic/tick.png +0 -0
- psychopy/app/Resources/classic/tick@2x.png +0 -0
- psychopy/app/Resources/classic/undo.png +0 -0
- psychopy/app/Resources/classic/undo32.png +0 -0
- psychopy/app/Resources/classic/undo@2x.png +0 -0
- psychopy/app/Resources/classic/unstarred.png +0 -0
- psychopy/app/Resources/classic/unstarred@2x.png +0 -0
- psychopy/app/Resources/classic/user_none.png +0 -0
- psychopy/app/Resources/classic/view-refresh16.png +0 -0
- psychopy/app/Resources/classic/viewbtn.png +0 -0
- psychopy/app/Resources/classic/viewbtn16.png +0 -0
- psychopy/app/Resources/classic/viewbtn16@2x.png +0 -0
- psychopy/app/Resources/classic/viewbtn@2x.png +0 -0
- psychopy/app/Resources/classic/windows16.png +0 -0
- psychopy/app/Resources/classic/windows16@2x.png +0 -0
- psychopy/app/Resources/coder.ico +0 -0
- psychopy/app/Resources/dark/FlowBottom_CompLeft.png +0 -0
- psychopy/app/Resources/dark/FlowBottom_CompRight.png +0 -0
- psychopy/app/Resources/dark/FlowTop_CompLeft.png +0 -0
- psychopy/app/Resources/dark/FlowTop_CompRight.png +0 -0
- psychopy/app/Resources/dark/README.txt +3 -0
- psychopy/app/Resources/dark/__init__.py +0 -0
- psychopy/app/Resources/dark/add.png +0 -0
- psychopy/app/Resources/dark/add@2x.png +0 -0
- psychopy/app/Resources/dark/addExp32.png +0 -0
- psychopy/app/Resources/dark/addExp32@2x.png +0 -0
- psychopy/app/Resources/dark/add_many.png +0 -0
- psychopy/app/Resources/dark/add_many@2x.png +0 -0
- psychopy/app/Resources/dark/alerts.png +0 -0
- psychopy/app/Resources/dark/alerts@2x.png +0 -0
- psychopy/app/Resources/dark/beta.png +0 -0
- psychopy/app/Resources/dark/beta@2x.png +0 -0
- psychopy/app/Resources/dark/browser.png +0 -0
- psychopy/app/Resources/dark/browser@2x.png +0 -0
- psychopy/app/Resources/dark/bug16.png +0 -0
- psychopy/app/Resources/dark/bug16@2x.png +0 -0
- psychopy/app/Resources/dark/case.png +0 -0
- psychopy/app/Resources/dark/case@2x.png +0 -0
- psychopy/app/Resources/dark/circle_mask.png +0 -0
- psychopy/app/Resources/dark/circle_mask@2x.png +0 -0
- psychopy/app/Resources/dark/clear.png +0 -0
- psychopy/app/Resources/dark/clear@2x.png +0 -0
- psychopy/app/Resources/dark/coderclass16.png +0 -0
- psychopy/app/Resources/dark/coderclass16@2x.png +0 -0
- psychopy/app/Resources/dark/coderfunc16.png +0 -0
- psychopy/app/Resources/dark/coderfunc16@2x.png +0 -0
- psychopy/app/Resources/dark/coderimport16.png +0 -0
- psychopy/app/Resources/dark/coderimport16@2x.png +0 -0
- psychopy/app/Resources/dark/coderjs.png +0 -0
- psychopy/app/Resources/dark/coderjs@2x.png +0 -0
- psychopy/app/Resources/dark/coderpython.png +0 -0
- psychopy/app/Resources/dark/coderpython@2x.png +0 -0
- psychopy/app/Resources/dark/codervar16.png +0 -0
- psychopy/app/Resources/dark/codervar16@2x.png +0 -0
- psychopy/app/Resources/dark/cogwindow32.png +0 -0
- psychopy/app/Resources/dark/cogwindow32@2x.png +0 -0
- psychopy/app/Resources/dark/color32.png +0 -0
- psychopy/app/Resources/dark/color32@2x.png +0 -0
- psychopy/app/Resources/dark/compile_js.png +0 -0
- psychopy/app/Resources/dark/compile_js@2x.png +0 -0
- psychopy/app/Resources/dark/compile_py.png +0 -0
- psychopy/app/Resources/dark/compile_py@2x.png +0 -0
- psychopy/app/Resources/dark/copy16.png +0 -0
- psychopy/app/Resources/dark/copy16@2x.png +0 -0
- psychopy/app/Resources/dark/currentFile16.png +0 -0
- psychopy/app/Resources/dark/currentFile16@2x.png +0 -0
- psychopy/app/Resources/dark/delete16.png +0 -0
- psychopy/app/Resources/dark/delete16@2x.png +0 -0
- psychopy/app/Resources/dark/desktop.png +0 -0
- psychopy/app/Resources/dark/desktop@2x.png +0 -0
- psychopy/app/Resources/dark/devices.png +0 -0
- psychopy/app/Resources/dark/devices@2x.png +0 -0
- psychopy/app/Resources/dark/dirup16.png +0 -0
- psychopy/app/Resources/dark/dirup16@2x.png +0 -0
- psychopy/app/Resources/dark/docclose16.png +0 -0
- psychopy/app/Resources/dark/docclose16@2x.png +0 -0
- psychopy/app/Resources/dark/download.png +0 -0
- psychopy/app/Resources/dark/download@2x.png +0 -0
- psychopy/app/Resources/dark/edit.png +0 -0
- psychopy/app/Resources/dark/edit@2x.png +0 -0
- psychopy/app/Resources/dark/editbtn16.png +0 -0
- psychopy/app/Resources/dark/editbtn16@2x.png +0 -0
- psychopy/app/Resources/dark/email.png +0 -0
- psychopy/app/Resources/dark/email@2x.png +0 -0
- psychopy/app/Resources/dark/experiment.png +0 -0
- psychopy/app/Resources/dark/experiment@2x.png +0 -0
- psychopy/app/Resources/dark/expsettings.png +0 -0
- psychopy/app/Resources/dark/expsettings@2x.png +0 -0
- psychopy/app/Resources/dark/file.png +0 -0
- psychopy/app/Resources/dark/file@16w.png +0 -0
- psychopy/app/Resources/dark/file@16w@2x.png +0 -0
- psychopy/app/Resources/dark/file@2x.png +0 -0
- psychopy/app/Resources/dark/fileaudio.png +0 -0
- psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
- psychopy/app/Resources/dark/filecss.png +0 -0
- psychopy/app/Resources/dark/filecss@2x.png +0 -0
- psychopy/app/Resources/dark/filecsv.png +0 -0
- psychopy/app/Resources/dark/filecsv@2x.png +0 -0
- psychopy/app/Resources/dark/filedesign.png +0 -0
- psychopy/app/Resources/dark/filedesign@2x.png +0 -0
- psychopy/app/Resources/dark/filefont.png +0 -0
- psychopy/app/Resources/dark/filefont@2x.png +0 -0
- psychopy/app/Resources/dark/filegit.png +0 -0
- psychopy/app/Resources/dark/filegit@2x.png +0 -0
- psychopy/app/Resources/dark/filehtml.png +0 -0
- psychopy/app/Resources/dark/filehtml@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage.png +0 -0
- psychopy/app/Resources/dark/fileimage@2x.png +0 -0
- psychopy/app/Resources/dark/fileinfo.png +0 -0
- psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
- psychopy/app/Resources/dark/filejs.png +0 -0
- psychopy/app/Resources/dark/filejs@2x.png +0 -0
- psychopy/app/Resources/dark/filejson.png +0 -0
- psychopy/app/Resources/dark/filejson@2x.png +0 -0
- psychopy/app/Resources/dark/filenew.png +0 -0
- psychopy/app/Resources/dark/filenew32.png +0 -0
- psychopy/app/Resources/dark/filenew32@2x.png +0 -0
- psychopy/app/Resources/dark/filenew@2x.png +0 -0
- psychopy/app/Resources/dark/fileopen.png +0 -0
- psychopy/app/Resources/dark/fileopen32.png +0 -0
- psychopy/app/Resources/dark/fileopen32@2x.png +0 -0
- psychopy/app/Resources/dark/fileopen@2x.png +0 -0
- psychopy/app/Resources/dark/filepkg.png +0 -0
- psychopy/app/Resources/dark/filepkg@2x.png +0 -0
- psychopy/app/Resources/dark/filepsyexp.png +0 -0
- psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/dark/filepy.png +0 -0
- psychopy/app/Resources/dark/filepy@2x.png +0 -0
- psychopy/app/Resources/dark/filesave.png +0 -0
- psychopy/app/Resources/dark/filesave32.png +0 -0
- psychopy/app/Resources/dark/filesave32@2x.png +0 -0
- psychopy/app/Resources/dark/filesave@2x.png +0 -0
- psychopy/app/Resources/dark/filesaveas.png +0 -0
- psychopy/app/Resources/dark/filesaveas32.png +0 -0
- psychopy/app/Resources/dark/filesaveas32@2x.png +0 -0
- psychopy/app/Resources/dark/filesaveas@2x.png +0 -0
- psychopy/app/Resources/dark/filetxt.png +0 -0
- psychopy/app/Resources/dark/filetxt@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown.png +0 -0
- psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
- psychopy/app/Resources/dark/filevideo.png +0 -0
- psychopy/app/Resources/dark/filevideo@2x.png +0 -0
- psychopy/app/Resources/dark/filter.png +0 -0
- psychopy/app/Resources/dark/filter@2x.png +0 -0
- psychopy/app/Resources/dark/find.png +0 -0
- psychopy/app/Resources/dark/find@2x.png +0 -0
- psychopy/app/Resources/dark/folder-open16.png +0 -0
- psychopy/app/Resources/dark/folder-open16@2x.png +0 -0
- psychopy/app/Resources/dark/folder16.png +0 -0
- psychopy/app/Resources/dark/folder16@2x.png +0 -0
- psychopy/app/Resources/dark/foldernew16.png +0 -0
- psychopy/app/Resources/dark/foldernew16@2x.png +0 -0
- psychopy/app/Resources/dark/fork.png +0 -0
- psychopy/app/Resources/dark/fork@2x.png +0 -0
- psychopy/app/Resources/dark/github.png +0 -0
- psychopy/app/Resources/dark/github@2x.png +0 -0
- psychopy/app/Resources/dark/globe.png +0 -0
- psychopy/app/Resources/dark/globe@2x.png +0 -0
- psychopy/app/Resources/dark/globe_bug.png +0 -0
- psychopy/app/Resources/dark/globe_bug@2x.png +0 -0
- psychopy/app/Resources/dark/globe_greensync.png +0 -0
- psychopy/app/Resources/dark/globe_greensync@2x.png +0 -0
- psychopy/app/Resources/dark/globe_info.png +0 -0
- psychopy/app/Resources/dark/globe_info@2x.png +0 -0
- psychopy/app/Resources/dark/globe_magnifier.png +0 -0
- psychopy/app/Resources/dark/globe_magnifier@2x.png +0 -0
- psychopy/app/Resources/dark/globe_run.png +0 -0
- psychopy/app/Resources/dark/globe_run@2x.png +0 -0
- psychopy/app/Resources/dark/globe_user.png +0 -0
- psychopy/app/Resources/dark/globe_user@2x.png +0 -0
- psychopy/app/Resources/dark/goto.png +0 -0
- psychopy/app/Resources/dark/goto@2x.png +0 -0
- psychopy/app/Resources/dark/greendot.png +0 -0
- psychopy/app/Resources/dark/greendot@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe.png +0 -0
- psychopy/app/Resources/dark/greenglobe@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_bug.png +0 -0
- psychopy/app/Resources/dark/greenglobe_bug@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_greensync.png +0 -0
- psychopy/app/Resources/dark/greenglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_info.png +0 -0
- psychopy/app/Resources/dark/greenglobe_info@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_magnifier.png +0 -0
- psychopy/app/Resources/dark/greenglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_run.png +0 -0
- psychopy/app/Resources/dark/greenglobe_run@2x.png +0 -0
- psychopy/app/Resources/dark/greenglobe_user.png +0 -0
- psychopy/app/Resources/dark/greenglobe_user@2x.png +0 -0
- psychopy/app/Resources/dark/greydot.png +0 -0
- psychopy/app/Resources/dark/greydot@2x.png +0 -0
- psychopy/app/Resources/dark/greytick.png +0 -0
- psychopy/app/Resources/dark/greytick@2x.png +0 -0
- psychopy/app/Resources/dark/invalid_img.png +0 -0
- psychopy/app/Resources/dark/jsPilot.png +0 -0
- psychopy/app/Resources/dark/jsPilot@2x.png +0 -0
- psychopy/app/Resources/dark/jsRun.png +0 -0
- psychopy/app/Resources/dark/jsRun@2x.png +0 -0
- psychopy/app/Resources/dark/libroot16.png +0 -0
- psychopy/app/Resources/dark/libroot16@2x.png +0 -0
- psychopy/app/Resources/dark/loop.png +0 -0
- psychopy/app/Resources/dark/loop@2x.png +0 -0
- psychopy/app/Resources/dark/monitor16.png +0 -0
- psychopy/app/Resources/dark/monitor16@2x.png +0 -0
- psychopy/app/Resources/dark/monitors.png +0 -0
- psychopy/app/Resources/dark/monitors32.png +0 -0
- psychopy/app/Resources/dark/monitors32@2x.png +0 -0
- psychopy/app/Resources/dark/monitors@2x.png +0 -0
- psychopy/app/Resources/dark/orangedot.png +0 -0
- psychopy/app/Resources/dark/orangedot@2x.png +0 -0
- psychopy/app/Resources/dark/pavlovia.png +0 -0
- psychopy/app/Resources/dark/pavlovia16.png +0 -0
- psychopy/app/Resources/dark/pavlovia16@2x.png +0 -0
- psychopy/app/Resources/dark/pavlovia@2x.png +0 -0
- psychopy/app/Resources/dark/pavsync.png +0 -0
- psychopy/app/Resources/dark/pavsync@2x.png +0 -0
- psychopy/app/Resources/dark/person_off.png +0 -0
- psychopy/app/Resources/dark/person_off@2x.png +0 -0
- psychopy/app/Resources/dark/person_on.png +0 -0
- psychopy/app/Resources/dark/person_on@2x.png +0 -0
- psychopy/app/Resources/dark/photometer.png +0 -0
- psychopy/app/Resources/dark/photometer@2x.png +0 -0
- psychopy/app/Resources/dark/plugin16.png +0 -0
- psychopy/app/Resources/dark/plugin16@2x.png +0 -0
- psychopy/app/Resources/dark/plugins32.png +0 -0
- psychopy/app/Resources/dark/plugins32@2x.png +0 -0
- psychopy/app/Resources/dark/plus.png +0 -0
- psychopy/app/Resources/dark/plus@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-app.png +0 -0
- psychopy/app/Resources/dark/preferences-app48.png +0 -0
- psychopy/app/Resources/dark/preferences-app48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-app@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-conn.png +0 -0
- psychopy/app/Resources/dark/preferences-conn48.png +0 -0
- psychopy/app/Resources/dark/preferences-conn48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-conn@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-debug.png +0 -0
- psychopy/app/Resources/dark/preferences-debug@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-general.png +0 -0
- psychopy/app/Resources/dark/preferences-general48.png +0 -0
- psychopy/app/Resources/dark/preferences-general48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-general@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware48.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-hardware@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard48.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard48@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-keyboard@2x.png +0 -0
- psychopy/app/Resources/dark/preferences-pilot.png +0 -0
- psychopy/app/Resources/dark/preferences-pilot@2x.png +0 -0
- psychopy/app/Resources/dark/preferences32.png +0 -0
- psychopy/app/Resources/dark/preferences32@2x.png +0 -0
- psychopy/app/Resources/dark/pyPilot.png +0 -0
- psychopy/app/Resources/dark/pyPilot@2x.png +0 -0
- psychopy/app/Resources/dark/pyRun.png +0 -0
- psychopy/app/Resources/dark/pyRun@2x.png +0 -0
- psychopy/app/Resources/dark/reddot.png +0 -0
- psychopy/app/Resources/dark/reddot@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe.png +0 -0
- psychopy/app/Resources/dark/redglobe@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_bug.png +0 -0
- psychopy/app/Resources/dark/redglobe_bug@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_greensync.png +0 -0
- psychopy/app/Resources/dark/redglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_info.png +0 -0
- psychopy/app/Resources/dark/redglobe_info@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_magnifier.png +0 -0
- psychopy/app/Resources/dark/redglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_run.png +0 -0
- psychopy/app/Resources/dark/redglobe_run@2x.png +0 -0
- psychopy/app/Resources/dark/redglobe_user.png +0 -0
- psychopy/app/Resources/dark/redglobe_user@2x.png +0 -0
- psychopy/app/Resources/dark/redo.png +0 -0
- psychopy/app/Resources/dark/redo32.png +0 -0
- psychopy/app/Resources/dark/redo32@2x.png +0 -0
- psychopy/app/Resources/dark/redo@2x.png +0 -0
- psychopy/app/Resources/dark/regex.png +0 -0
- psychopy/app/Resources/dark/regex@2x.png +0 -0
- psychopy/app/Resources/dark/removeExp32.png +0 -0
- psychopy/app/Resources/dark/removeExp32@2x.png +0 -0
- psychopy/app/Resources/dark/rename16.png +0 -0
- psychopy/app/Resources/dark/rename16@2x.png +0 -0
- psychopy/app/Resources/dark/restart.png +0 -0
- psychopy/app/Resources/dark/restart@2x.png +0 -0
- psychopy/app/Resources/dark/runner.png +0 -0
- psychopy/app/Resources/dark/runner@2x.png +0 -0
- psychopy/app/Resources/dark/runnerPilot.png +0 -0
- psychopy/app/Resources/dark/runnerPilot@2x.png +0 -0
- psychopy/app/Resources/dark/savebtn16.png +0 -0
- psychopy/app/Resources/dark/savebtn16@2x.png +0 -0
- psychopy/app/Resources/dark/search.png +0 -0
- psychopy/app/Resources/dark/search@2x.png +0 -0
- psychopy/app/Resources/dark/showBuilder.png +0 -0
- psychopy/app/Resources/dark/showBuilder@2x.png +0 -0
- psychopy/app/Resources/dark/showCoder.png +0 -0
- psychopy/app/Resources/dark/showCoder@2x.png +0 -0
- psychopy/app/Resources/dark/showRunner.png +0 -0
- psychopy/app/Resources/dark/showRunner@2x.png +0 -0
- psychopy/app/Resources/dark/starred.png +0 -0
- psychopy/app/Resources/dark/starred@2x.png +0 -0
- psychopy/app/Resources/dark/start.png +0 -0
- psychopy/app/Resources/dark/start@2x.png +0 -0
- psychopy/app/Resources/dark/stdout.png +0 -0
- psychopy/app/Resources/dark/stdout@2x.png +0 -0
- psychopy/app/Resources/dark/stop.png +0 -0
- psychopy/app/Resources/dark/stop32.png +0 -0
- psychopy/app/Resources/dark/stop32@2x.png +0 -0
- psychopy/app/Resources/dark/stop@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlBot.png +0 -0
- psychopy/app/Resources/dark/switchCtrlBot@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlLeft.png +0 -0
- psychopy/app/Resources/dark/switchCtrlLeft@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlRight.png +0 -0
- psychopy/app/Resources/dark/switchCtrlRight@2x.png +0 -0
- psychopy/app/Resources/dark/switchCtrlTop.png +0 -0
- psychopy/app/Resources/dark/switchCtrlTop@2x.png +0 -0
- psychopy/app/Resources/dark/tick.png +0 -0
- psychopy/app/Resources/dark/tick@2x.png +0 -0
- psychopy/app/Resources/dark/undo.png +0 -0
- psychopy/app/Resources/dark/undo32.png +0 -0
- psychopy/app/Resources/dark/undo32@2x.png +0 -0
- psychopy/app/Resources/dark/undo@2x.png +0 -0
- psychopy/app/Resources/dark/unstarred.png +0 -0
- psychopy/app/Resources/dark/unstarred@2x.png +0 -0
- psychopy/app/Resources/dark/user_none.png +0 -0
- psychopy/app/Resources/dark/view-refresh16.png +0 -0
- psychopy/app/Resources/dark/view-refresh16@2x.png +0 -0
- psychopy/app/Resources/dark/viewbtn16.png +0 -0
- psychopy/app/Resources/dark/viewbtn16@2x.png +0 -0
- psychopy/app/Resources/dark/windows16.png +0 -0
- psychopy/app/Resources/dark/windows16@2x.png +0 -0
- psychopy/app/Resources/light/FlowBottom_CompLeft.png +0 -0
- psychopy/app/Resources/light/FlowBottom_CompRight.png +0 -0
- psychopy/app/Resources/light/FlowTop_CompLeft.png +0 -0
- psychopy/app/Resources/light/FlowTop_CompRight.png +0 -0
- psychopy/app/Resources/light/README.txt +3 -0
- psychopy/app/Resources/light/__init__.py +0 -0
- psychopy/app/Resources/light/add.png +0 -0
- psychopy/app/Resources/light/add@2x.png +0 -0
- psychopy/app/Resources/light/addExp32.png +0 -0
- psychopy/app/Resources/light/addExp32@2x.png +0 -0
- psychopy/app/Resources/light/add_many.png +0 -0
- psychopy/app/Resources/light/add_many@2x.png +0 -0
- psychopy/app/Resources/light/alerts.png +0 -0
- psychopy/app/Resources/light/alerts@2x.png +0 -0
- psychopy/app/Resources/light/beta.png +0 -0
- psychopy/app/Resources/light/beta@2x.png +0 -0
- psychopy/app/Resources/light/browser.png +0 -0
- psychopy/app/Resources/light/browser@2x.png +0 -0
- psychopy/app/Resources/light/bug16.png +0 -0
- psychopy/app/Resources/light/bug16@2x.png +0 -0
- psychopy/app/Resources/light/case.png +0 -0
- psychopy/app/Resources/light/case@2x.png +0 -0
- psychopy/app/Resources/light/circle_mask.png +0 -0
- psychopy/app/Resources/light/circle_mask@2x.png +0 -0
- psychopy/app/Resources/light/clear.png +0 -0
- psychopy/app/Resources/light/clear@2x.png +0 -0
- psychopy/app/Resources/light/coderclass16.png +0 -0
- psychopy/app/Resources/light/coderclass16@2x.png +0 -0
- psychopy/app/Resources/light/coderfunc16.png +0 -0
- psychopy/app/Resources/light/coderfunc16@2x.png +0 -0
- psychopy/app/Resources/light/coderimport16.png +0 -0
- psychopy/app/Resources/light/coderimport16@2x.png +0 -0
- psychopy/app/Resources/light/coderjs.png +0 -0
- psychopy/app/Resources/light/coderjs@2x.png +0 -0
- psychopy/app/Resources/light/coderpython.png +0 -0
- psychopy/app/Resources/light/coderpython@2x.png +0 -0
- psychopy/app/Resources/light/codervar16.png +0 -0
- psychopy/app/Resources/light/codervar16@2x.png +0 -0
- psychopy/app/Resources/light/cogwindow32.png +0 -0
- psychopy/app/Resources/light/cogwindow32@2x.png +0 -0
- psychopy/app/Resources/light/color16.png +0 -0
- psychopy/app/Resources/light/color16@2x.png +0 -0
- psychopy/app/Resources/light/color32.png +0 -0
- psychopy/app/Resources/light/color32@2x.png +0 -0
- psychopy/app/Resources/light/compile_js.png +0 -0
- psychopy/app/Resources/light/compile_js@2x.png +0 -0
- psychopy/app/Resources/light/compile_py.png +0 -0
- psychopy/app/Resources/light/compile_py@2x.png +0 -0
- psychopy/app/Resources/light/copy16.png +0 -0
- psychopy/app/Resources/light/copy16@2x.png +0 -0
- psychopy/app/Resources/light/currentFile16.png +0 -0
- psychopy/app/Resources/light/currentFile16@2x.png +0 -0
- psychopy/app/Resources/light/delete16.png +0 -0
- psychopy/app/Resources/light/delete16@2x.png +0 -0
- psychopy/app/Resources/light/delete8.png +0 -0
- psychopy/app/Resources/light/desktop.png +0 -0
- psychopy/app/Resources/light/desktop@2x.png +0 -0
- psychopy/app/Resources/light/devices.png +0 -0
- psychopy/app/Resources/light/devices@2x.png +0 -0
- psychopy/app/Resources/light/dirup16.png +0 -0
- psychopy/app/Resources/light/dirup16@2x.png +0 -0
- psychopy/app/Resources/light/docclose16.png +0 -0
- psychopy/app/Resources/light/docclose16@2x.png +0 -0
- psychopy/app/Resources/light/download.png +0 -0
- psychopy/app/Resources/light/download@2x.png +0 -0
- psychopy/app/Resources/light/edit.png +0 -0
- psychopy/app/Resources/light/edit@2x.png +0 -0
- psychopy/app/Resources/light/editbtn16.png +0 -0
- psychopy/app/Resources/light/editbtn16@2x.png +0 -0
- psychopy/app/Resources/light/email.png +0 -0
- psychopy/app/Resources/light/email@2x.png +0 -0
- psychopy/app/Resources/light/experiment.png +0 -0
- psychopy/app/Resources/light/experiment@2x.png +0 -0
- psychopy/app/Resources/light/expsettings.png +0 -0
- psychopy/app/Resources/light/expsettings@2x.png +0 -0
- psychopy/app/Resources/light/file.png +0 -0
- psychopy/app/Resources/light/file@2x.png +0 -0
- psychopy/app/Resources/light/fileaudio.png +0 -0
- psychopy/app/Resources/light/fileaudio@2x.png +0 -0
- psychopy/app/Resources/light/filecss.png +0 -0
- psychopy/app/Resources/light/filecss@2x.png +0 -0
- psychopy/app/Resources/light/filecsv.png +0 -0
- psychopy/app/Resources/light/filecsv@2x.png +0 -0
- psychopy/app/Resources/light/filedesign.png +0 -0
- psychopy/app/Resources/light/filedesign@2x.png +0 -0
- psychopy/app/Resources/light/filefont.png +0 -0
- psychopy/app/Resources/light/filefont@2x.png +0 -0
- psychopy/app/Resources/light/filegit.png +0 -0
- psychopy/app/Resources/light/filegit@2x.png +0 -0
- psychopy/app/Resources/light/filehtml.png +0 -0
- psychopy/app/Resources/light/filehtml@2x.png +0 -0
- psychopy/app/Resources/light/fileimage.png +0 -0
- psychopy/app/Resources/light/fileimage@2x.png +0 -0
- psychopy/app/Resources/light/fileinfo.png +0 -0
- psychopy/app/Resources/light/fileinfo@2x.png +0 -0
- psychopy/app/Resources/light/filejs.png +0 -0
- psychopy/app/Resources/light/filejs@2x.png +0 -0
- psychopy/app/Resources/light/filejson.png +0 -0
- psychopy/app/Resources/light/filejson@2x.png +0 -0
- psychopy/app/Resources/light/filenew.png +0 -0
- psychopy/app/Resources/light/filenew32.png +0 -0
- psychopy/app/Resources/light/filenew32@2x.png +0 -0
- psychopy/app/Resources/light/filenew@2x.png +0 -0
- psychopy/app/Resources/light/fileopen.png +0 -0
- psychopy/app/Resources/light/fileopen32.png +0 -0
- psychopy/app/Resources/light/fileopen32@2x.png +0 -0
- psychopy/app/Resources/light/fileopen@2x.png +0 -0
- psychopy/app/Resources/light/filepkg.png +0 -0
- psychopy/app/Resources/light/filepkg@2x.png +0 -0
- psychopy/app/Resources/light/filepsyexp.png +0 -0
- psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/light/filepy.png +0 -0
- psychopy/app/Resources/light/filepy@2x.png +0 -0
- psychopy/app/Resources/light/filesave.png +0 -0
- psychopy/app/Resources/light/filesave32.png +0 -0
- psychopy/app/Resources/light/filesave32@2x.png +0 -0
- psychopy/app/Resources/light/filesave@2x.png +0 -0
- psychopy/app/Resources/light/filesaveas.png +0 -0
- psychopy/app/Resources/light/filesaveas32.png +0 -0
- psychopy/app/Resources/light/filesaveas32@2x.png +0 -0
- psychopy/app/Resources/light/filesaveas@2x.png +0 -0
- psychopy/app/Resources/light/filetxt.png +0 -0
- psychopy/app/Resources/light/filetxt@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown.png +0 -0
- psychopy/app/Resources/light/fileunknown@2x.png +0 -0
- psychopy/app/Resources/light/filevideo.png +0 -0
- psychopy/app/Resources/light/filevideo@2x.png +0 -0
- psychopy/app/Resources/light/filter.png +0 -0
- psychopy/app/Resources/light/filter@2x.png +0 -0
- psychopy/app/Resources/light/find.png +0 -0
- psychopy/app/Resources/light/find@2x.png +0 -0
- psychopy/app/Resources/light/folder-open16.png +0 -0
- psychopy/app/Resources/light/folder-open16@2x.png +0 -0
- psychopy/app/Resources/light/folder16.png +0 -0
- psychopy/app/Resources/light/folder16@2x.png +0 -0
- psychopy/app/Resources/light/foldernew16.png +0 -0
- psychopy/app/Resources/light/foldernew16@2x.png +0 -0
- psychopy/app/Resources/light/fork.png +0 -0
- psychopy/app/Resources/light/fork@2x.png +0 -0
- psychopy/app/Resources/light/github.png +0 -0
- psychopy/app/Resources/light/github@2x.png +0 -0
- psychopy/app/Resources/light/globe.png +0 -0
- psychopy/app/Resources/light/globe@2x.png +0 -0
- psychopy/app/Resources/light/globe_bug.png +0 -0
- psychopy/app/Resources/light/globe_bug@2x.png +0 -0
- psychopy/app/Resources/light/globe_greensync.png +0 -0
- psychopy/app/Resources/light/globe_greensync@2x.png +0 -0
- psychopy/app/Resources/light/globe_info.png +0 -0
- psychopy/app/Resources/light/globe_info@2x.png +0 -0
- psychopy/app/Resources/light/globe_magnifier.png +0 -0
- psychopy/app/Resources/light/globe_magnifier@2x.png +0 -0
- psychopy/app/Resources/light/globe_run.png +0 -0
- psychopy/app/Resources/light/globe_run@2x.png +0 -0
- psychopy/app/Resources/light/globe_user.png +0 -0
- psychopy/app/Resources/light/globe_user@2x.png +0 -0
- psychopy/app/Resources/light/goto16.png +0 -0
- psychopy/app/Resources/light/goto16@2x.png +0 -0
- psychopy/app/Resources/light/greendot.png +0 -0
- psychopy/app/Resources/light/greendot@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe.png +0 -0
- psychopy/app/Resources/light/greenglobe@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_bug.png +0 -0
- psychopy/app/Resources/light/greenglobe_bug@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_greensync.png +0 -0
- psychopy/app/Resources/light/greenglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_info.png +0 -0
- psychopy/app/Resources/light/greenglobe_info@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_magnifier.png +0 -0
- psychopy/app/Resources/light/greenglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_run.png +0 -0
- psychopy/app/Resources/light/greenglobe_run@2x.png +0 -0
- psychopy/app/Resources/light/greenglobe_user.png +0 -0
- psychopy/app/Resources/light/greenglobe_user@2x.png +0 -0
- psychopy/app/Resources/light/greydot.png +0 -0
- psychopy/app/Resources/light/greydot@2x.png +0 -0
- psychopy/app/Resources/light/greytick.png +0 -0
- psychopy/app/Resources/light/greytick@2x.png +0 -0
- psychopy/app/Resources/light/invalid_img.png +0 -0
- psychopy/app/Resources/light/jsPilot.png +0 -0
- psychopy/app/Resources/light/jsPilot@2x.png +0 -0
- psychopy/app/Resources/light/jsRun.png +0 -0
- psychopy/app/Resources/light/jsRun@2x.png +0 -0
- psychopy/app/Resources/light/libroot16.png +0 -0
- psychopy/app/Resources/light/libroot16@2x.png +0 -0
- psychopy/app/Resources/light/loop.png +0 -0
- psychopy/app/Resources/light/loop@2x.png +0 -0
- psychopy/app/Resources/light/monitor16.png +0 -0
- psychopy/app/Resources/light/monitor16@2x.png +0 -0
- psychopy/app/Resources/light/monitors.png +0 -0
- psychopy/app/Resources/light/monitors32.png +0 -0
- psychopy/app/Resources/light/monitors32@2x.png +0 -0
- psychopy/app/Resources/light/monitors@2x.png +0 -0
- psychopy/app/Resources/light/orangedot.png +0 -0
- psychopy/app/Resources/light/orangedot@2x.png +0 -0
- psychopy/app/Resources/light/pavlovia.png +0 -0
- psychopy/app/Resources/light/pavlovia16.png +0 -0
- psychopy/app/Resources/light/pavlovia16@2x.png +0 -0
- psychopy/app/Resources/light/pavlovia@2x.png +0 -0
- psychopy/app/Resources/light/pavsync.png +0 -0
- psychopy/app/Resources/light/pavsync@2x.png +0 -0
- psychopy/app/Resources/light/person_off.png +0 -0
- psychopy/app/Resources/light/person_off@2x.png +0 -0
- psychopy/app/Resources/light/person_on.png +0 -0
- psychopy/app/Resources/light/person_on@2x.png +0 -0
- psychopy/app/Resources/light/photometer.png +0 -0
- psychopy/app/Resources/light/photometer@2x.png +0 -0
- psychopy/app/Resources/light/plugin16.png +0 -0
- psychopy/app/Resources/light/plugin16@2x.png +0 -0
- psychopy/app/Resources/light/plugins32.png +0 -0
- psychopy/app/Resources/light/plugins32@2x.png +0 -0
- psychopy/app/Resources/light/plus.png +0 -0
- psychopy/app/Resources/light/plus@2x.png +0 -0
- psychopy/app/Resources/light/preferences-app.png +0 -0
- psychopy/app/Resources/light/preferences-app48.png +0 -0
- psychopy/app/Resources/light/preferences-app48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-app@2x.png +0 -0
- psychopy/app/Resources/light/preferences-conn.png +0 -0
- psychopy/app/Resources/light/preferences-conn48.png +0 -0
- psychopy/app/Resources/light/preferences-conn48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-conn@2x.png +0 -0
- psychopy/app/Resources/light/preferences-general.png +0 -0
- psychopy/app/Resources/light/preferences-general48.png +0 -0
- psychopy/app/Resources/light/preferences-general48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-general@2x.png +0 -0
- psychopy/app/Resources/light/preferences-hardware.png +0 -0
- psychopy/app/Resources/light/preferences-hardware48.png +0 -0
- psychopy/app/Resources/light/preferences-hardware48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-hardware@2x.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard48.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard48@2x.png +0 -0
- psychopy/app/Resources/light/preferences-keyboard@2x.png +0 -0
- psychopy/app/Resources/light/preferences-pilot.png +0 -0
- psychopy/app/Resources/light/preferences-pilot@2x.png +0 -0
- psychopy/app/Resources/light/preferences32.png +0 -0
- psychopy/app/Resources/light/preferences32@2x.png +0 -0
- psychopy/app/Resources/light/pyPilot.png +0 -0
- psychopy/app/Resources/light/pyPilot@2x.png +0 -0
- psychopy/app/Resources/light/pyRun.png +0 -0
- psychopy/app/Resources/light/pyRun@2x.png +0 -0
- psychopy/app/Resources/light/reddot.png +0 -0
- psychopy/app/Resources/light/reddot@2x.png +0 -0
- psychopy/app/Resources/light/redglobe.png +0 -0
- psychopy/app/Resources/light/redglobe@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_bug.png +0 -0
- psychopy/app/Resources/light/redglobe_bug@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_greensync.png +0 -0
- psychopy/app/Resources/light/redglobe_greensync@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_info.png +0 -0
- psychopy/app/Resources/light/redglobe_info@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_magnifier.png +0 -0
- psychopy/app/Resources/light/redglobe_magnifier@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_run.png +0 -0
- psychopy/app/Resources/light/redglobe_run@2x.png +0 -0
- psychopy/app/Resources/light/redglobe_user.png +0 -0
- psychopy/app/Resources/light/redglobe_user@2x.png +0 -0
- psychopy/app/Resources/light/redo.png +0 -0
- psychopy/app/Resources/light/redo32.png +0 -0
- psychopy/app/Resources/light/redo32@2x.png +0 -0
- psychopy/app/Resources/light/redo@2x.png +0 -0
- psychopy/app/Resources/light/regex.png +0 -0
- psychopy/app/Resources/light/regex@2x.png +0 -0
- psychopy/app/Resources/light/removeExp32.png +0 -0
- psychopy/app/Resources/light/removeExp32@2x.png +0 -0
- psychopy/app/Resources/light/rename16.png +0 -0
- psychopy/app/Resources/light/rename16@2x.png +0 -0
- psychopy/app/Resources/light/restart.png +0 -0
- psychopy/app/Resources/light/restart@2x.png +0 -0
- psychopy/app/Resources/light/runner.png +0 -0
- psychopy/app/Resources/light/runner@2x.png +0 -0
- psychopy/app/Resources/light/runnerPilot.png +0 -0
- psychopy/app/Resources/light/runnerPilot@2x.png +0 -0
- psychopy/app/Resources/light/savebtn16.png +0 -0
- psychopy/app/Resources/light/savebtn16@2x.png +0 -0
- psychopy/app/Resources/light/search.png +0 -0
- psychopy/app/Resources/light/search@2x.png +0 -0
- psychopy/app/Resources/light/showBuilder.png +0 -0
- psychopy/app/Resources/light/showBuilder@2x.png +0 -0
- psychopy/app/Resources/light/showCoder.png +0 -0
- psychopy/app/Resources/light/showCoder@2x.png +0 -0
- psychopy/app/Resources/light/showRunner.png +0 -0
- psychopy/app/Resources/light/showRunner@2x.png +0 -0
- psychopy/app/Resources/light/starred.png +0 -0
- psychopy/app/Resources/light/starred@2x.png +0 -0
- psychopy/app/Resources/light/start.png +0 -0
- psychopy/app/Resources/light/start@2x.png +0 -0
- psychopy/app/Resources/light/stdout.png +0 -0
- psychopy/app/Resources/light/stdout@2x.png +0 -0
- psychopy/app/Resources/light/stop.png +0 -0
- psychopy/app/Resources/light/stop32.png +0 -0
- psychopy/app/Resources/light/stop32@2x.png +0 -0
- psychopy/app/Resources/light/stop@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlBot.png +0 -0
- psychopy/app/Resources/light/switchCtrlBot@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlLeft.png +0 -0
- psychopy/app/Resources/light/switchCtrlLeft@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlRight.png +0 -0
- psychopy/app/Resources/light/switchCtrlRight@2x.png +0 -0
- psychopy/app/Resources/light/switchCtrlTop.png +0 -0
- psychopy/app/Resources/light/switchCtrlTop@2x.png +0 -0
- psychopy/app/Resources/light/tick.png +0 -0
- psychopy/app/Resources/light/tick@2x.png +0 -0
- psychopy/app/Resources/light/undo.png +0 -0
- psychopy/app/Resources/light/undo32.png +0 -0
- psychopy/app/Resources/light/undo32@2x.png +0 -0
- psychopy/app/Resources/light/undo@2x.png +0 -0
- psychopy/app/Resources/light/unstarred.png +0 -0
- psychopy/app/Resources/light/unstarred@2x.png +0 -0
- psychopy/app/Resources/light/user_none.png +0 -0
- psychopy/app/Resources/light/view-refresh16.png +0 -0
- psychopy/app/Resources/light/view-refresh16@2x.png +0 -0
- psychopy/app/Resources/light/viewbtn16.png +0 -0
- psychopy/app/Resources/light/viewbtn16@2x.png +0 -0
- psychopy/app/Resources/light/windows16.png +0 -0
- psychopy/app/Resources/light/windows16@2x.png +0 -0
- psychopy/app/Resources/moveComponentIcons.py +50 -0
- psychopy/app/Resources/psychopy.desktop +13 -0
- psychopy/app/Resources/psychopy.icns +0 -0
- psychopy/app/Resources/psychopy.ico +0 -0
- psychopy/app/Resources/psychopy.png +0 -0
- psychopy/app/Resources/psychopy.xml +9 -0
- psychopy/app/Resources/psychopy@2x.png +0 -0
- psychopy/app/Resources/routine_templates/Basic.psyexp +344 -0
- psychopy/app/Resources/routine_templates/Misc.psyexp +228 -0
- psychopy/app/Resources/routine_templates/Online.psyexp +200 -0
- psychopy/app/Resources/routine_templates/Trials.psyexp +735 -0
- psychopy/app/Resources/routine_templates/readme.md +14 -0
- psychopy/app/Resources/runner.ico +0 -0
- psychopy/app/Resources/splash.png +0 -0
- psychopy/app/Resources/splash@2x.png +0 -0
- psychopy/app/Resources/tips.txt +45 -0
- psychopy/app/Resources/tips_ar_001.txt +45 -0
- psychopy/app/Resources/tips_fr_FR.txt +45 -0
- psychopy/app/Resources/tips_ja_JP.txt +42 -0
- psychopy/app/Resources/tips_zh_CN.txt +45 -0
- psychopy/app/Resources/window.ico +0 -0
- psychopy/app/__init__.py +339 -0
- psychopy/app/__main__.py +3 -0
- psychopy/app/_psychopyApp.py +1298 -0
- psychopy/app/appData.spec +58 -0
- psychopy/app/builder/__init__.py +5 -0
- psychopy/app/builder/builder.py +4738 -0
- psychopy/app/builder/dialogs/__init__.py +1910 -0
- psychopy/app/builder/dialogs/dlgsCode.py +631 -0
- psychopy/app/builder/dialogs/dlgsConditions.py +669 -0
- psychopy/app/builder/dialogs/findDlg.py +275 -0
- psychopy/app/builder/dialogs/paramCtrls.py +1802 -0
- psychopy/app/builder/validators.py +589 -0
- psychopy/app/coder/__init__.py +8 -0
- psychopy/app/coder/codeEditorBase.py +460 -0
- psychopy/app/coder/coder.py +3100 -0
- psychopy/app/coder/fileBrowser.py +714 -0
- psychopy/app/coder/folding.py +128 -0
- psychopy/app/coder/psychoParser.py +139 -0
- psychopy/app/coder/repl.py +496 -0
- psychopy/app/coder/sourceTree.py +302 -0
- psychopy/app/colorpicker/__init__.py +594 -0
- psychopy/app/colorpicker/ui.py +336 -0
- psychopy/app/connections/__init__.py +10 -0
- psychopy/app/connections/news.py +104 -0
- psychopy/app/connections/sendusage.py +61 -0
- psychopy/app/connections/updates.py +642 -0
- psychopy/app/console.py +164 -0
- psychopy/app/deviceManager/__init__.py +1 -0
- psychopy/app/deviceManager/addDialog.py +218 -0
- psychopy/app/deviceManager/dialog.py +185 -0
- psychopy/app/deviceManager/panel.py +191 -0
- psychopy/app/deviceManager/utils.py +60 -0
- psychopy/app/dialogs.py +664 -0
- psychopy/app/errorDlg.py +238 -0
- psychopy/app/frametracker.py +8 -0
- psychopy/app/idle.py +181 -0
- psychopy/app/jobs.py +676 -0
- psychopy/app/linuxconfig/__init__.py +153 -0
- psychopy/app/linuxconfig/ui.py +88 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +12695 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +11221 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.po +10195 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +11917 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +11924 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +11917 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +11084 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +11590 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +11091 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +11072 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +11071 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +11072 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +11268 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +11463 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +11288 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +10200 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +10199 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +11441 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +11069 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +12085 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +11929 -0
- psychopy/app/localizedStrings.py +386 -0
- psychopy/app/pavlovia_ui/__init__.py +22 -0
- psychopy/app/pavlovia_ui/_base.py +268 -0
- psychopy/app/pavlovia_ui/functions.py +176 -0
- psychopy/app/pavlovia_ui/menu.py +140 -0
- psychopy/app/pavlovia_ui/project.py +943 -0
- psychopy/app/pavlovia_ui/search.py +444 -0
- psychopy/app/pavlovia_ui/sync.py +137 -0
- psychopy/app/pavlovia_ui/user.py +264 -0
- psychopy/app/plugin_manager/__init__.py +5 -0
- psychopy/app/plugin_manager/dialog.py +402 -0
- psychopy/app/plugin_manager/output.py +132 -0
- psychopy/app/plugin_manager/packageIndex.py +303 -0
- psychopy/app/plugin_manager/packages.py +643 -0
- psychopy/app/plugin_manager/plugins.py +1363 -0
- psychopy/app/plugin_manager/utils.py +115 -0
- psychopy/app/preferencesDlg.py +771 -0
- psychopy/app/psychopyApp.py +207 -0
- psychopy/app/ribbon.py +1019 -0
- psychopy/app/runner/__init__.py +1 -0
- psychopy/app/runner/runner.py +1299 -0
- psychopy/app/runner/scriptProcess.py +363 -0
- psychopy/app/stdout/__init__.py +1 -0
- psychopy/app/stdout/stdOutRich.py +410 -0
- psychopy/app/sysInfoDlg.py +242 -0
- psychopy/app/themes/__init__.py +78 -0
- psychopy/app/themes/colors.py +201 -0
- psychopy/app/themes/css/contrast_black.css +112 -0
- psychopy/app/themes/css/contrast_white.css +115 -0
- psychopy/app/themes/css/dark.css +112 -0
- psychopy/app/themes/css/light.css +115 -0
- psychopy/app/themes/fonts.py +629 -0
- psychopy/app/themes/handlers.py +321 -0
- psychopy/app/themes/icons.py +267 -0
- psychopy/app/themes/spec/Classic.json +154 -0
- psychopy/app/themes/spec/ClassicDark.json +154 -0
- psychopy/app/themes/spec/GitHub.json +154 -0
- psychopy/app/themes/spec/HiVisDark.json +153 -0
- psychopy/app/themes/spec/HiVisLight.json +154 -0
- psychopy/app/themes/spec/MinimalDark.json +154 -0
- psychopy/app/themes/spec/MinimalLight.json +153 -0
- psychopy/app/themes/spec/PsychopyDark.json +231 -0
- psychopy/app/themes/spec/PsychopyLight.json +236 -0
- psychopy/app/themes/ui.py +74 -0
- psychopy/app/ui/__init__.py +184 -0
- psychopy/app/urls.py +31 -0
- psychopy/app/utils.py +1741 -0
- psychopy/app/viewer/__init__.py +0 -0
- psychopy/assets/Psychopy Window Favicon@16w.png +0 -0
- psychopy/assets/Psychopy Window Favicon@32w.png +0 -0
- psychopy/assets/USB-C.png +0 -0
- psychopy/assets/USB.png +0 -0
- psychopy/assets/__init__.py +0 -0
- psychopy/assets/click.png +0 -0
- psychopy/assets/clicknext.png +0 -0
- psychopy/assets/creditCard.png +0 -0
- psychopy/assets/default.mp3 +0 -0
- psychopy/assets/default.mp4 +0 -0
- psychopy/assets/default.png +0 -0
- psychopy/assets/fonts/Arvo-Bold.ttf +0 -0
- psychopy/assets/fonts/Arvo-BoldItalic.ttf +0 -0
- psychopy/assets/fonts/Arvo-Italic.ttf +0 -0
- psychopy/assets/fonts/Arvo-Regular.ttf +0 -0
- psychopy/assets/fonts/DejaVuSerif.ttf +0 -0
- psychopy/assets/fonts/IndieFlower-Regular.ttf +0 -0
- psychopy/assets/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- psychopy/assets/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
- psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Regular.ttf +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/templates/instruct1.png +0 -0
- psychopy/assets/templates/instruct2.png +0 -0
- psychopy/assets/touch.png +0 -0
- psychopy/assets/touchnext.png +0 -0
- psychopy/assets/voicekeyThresholdStim.wav +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 +619 -0
- psychopy/colors.py +1058 -0
- psychopy/compatibility.py +147 -0
- psychopy/constants.py +87 -0
- psychopy/contrib/__init__.py +0 -0
- psychopy/contrib/configobj/LICENSE +39 -0
- psychopy/contrib/configobj/__init__.py +2455 -0
- psychopy/contrib/configobj/_version.py +2 -0
- psychopy/contrib/configobj/validate.py +1458 -0
- psychopy/contrib/lazy_import.py +402 -0
- psychopy/contrib/mseq.py +273 -0
- psychopy/contrib/mseqSearch.py +183 -0
- psychopy/contrib/psi.py +100 -0
- psychopy/contrib/quest.py +484 -0
- psychopy/contrib/tesselate.py +188 -0
- psychopy/core.py +167 -0
- psychopy/data/__init__.py +45 -0
- psychopy/data/base.py +566 -0
- psychopy/data/counterbalance.py +210 -0
- psychopy/data/experiment.py +1049 -0
- psychopy/data/fit.py +248 -0
- psychopy/data/routine.py +94 -0
- psychopy/data/shelf.py +237 -0
- psychopy/data/staircase.py +2270 -0
- psychopy/data/trial.py +2505 -0
- psychopy/data/utils.py +858 -0
- psychopy/demos/__init__.py +0 -0
- psychopy/demos/builder/Design Templates/branchedExperiment/README.md +5 -0
- psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +354 -0
- psychopy/demos/builder/Design Templates/branchedExperiment/trialTypes.xlsx +0 -0
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/README.md +20 -0
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +286 -0
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/README.md +14 -0
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +340 -0
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/stairDefinitions.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/README.md +18 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/chooseBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/facesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/housesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +219 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/face03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/stims/house03.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/README.md +30 -0
- psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/assets/background.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/bang.mp3 +0 -0
- psychopy/demos/builder/Experiments/BART/assets/bang.wav +0 -0
- psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/bart.psyexp +844 -0
- psychopy/demos/builder/Experiments/BART/spreadsheets/conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +255 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/README.md +23 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/TIPI.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/bigFiveItems.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/demographics.xlsx +0 -0
- psychopy/demos/builder/Experiments/BigFiveInventory/mini_IPIP.xlsx +0 -0
- psychopy/demos/builder/Experiments/GoNoGo/conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +462 -0
- psychopy/demos/builder/Experiments/GoNoGo/go.png +0 -0
- psychopy/demos/builder/Experiments/GoNoGo/nogo.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/README.md +5 -0
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +494 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/goNoGo/readme.md +14 -0
- psychopy/demos/builder/Experiments/mentalRotation/F.png +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/FR.png +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRot.csv +33 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +646 -0
- psychopy/demos/builder/Experiments/mentalRotation/README.md +23 -0
- psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +509 -0
- psychopy/demos/builder/Experiments/navon/README.md +26 -0
- psychopy/demos/builder/Experiments/navon/bigHsmallH.png +0 -0
- psychopy/demos/builder/Experiments/navon/bigHsmallS.png +0 -0
- psychopy/demos/builder/Experiments/navon/bigSsmallH.png +0 -0
- psychopy/demos/builder/Experiments/navon/bigSsmallS.png +0 -0
- psychopy/demos/builder/Experiments/navon/mask.png +0 -0
- psychopy/demos/builder/Experiments/navon/stimuli.pptx +0 -0
- psychopy/demos/builder/Experiments/navon/trialTypes.xlsx +0 -0
- psychopy/demos/builder/Experiments/sternberg/README.md +14 -0
- psychopy/demos/builder/Experiments/sternberg/mainTrials.xlsx +0 -0
- psychopy/demos/builder/Experiments/sternberg/pracTrials.xlsx +0 -0
- psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +649 -0
- psychopy/demos/builder/Experiments/stroop/README.md +15 -0
- psychopy/demos/builder/Experiments/stroop/stroop.psyexp +321 -0
- psychopy/demos/builder/Experiments/stroop/trialTypes.csv +7 -0
- psychopy/demos/builder/Experiments/stroopExtended/README.md +14 -0
- psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +418 -0
- psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +418 -0
- psychopy/demos/builder/Experiments/stroopExtended/trialTypes.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopExtended/trialTypesReverse.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/README.md +27 -0
- psychopy/demos/builder/Experiments/stroopVoice/conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +382 -0
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +371 -0
- psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
- psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +308 -0
- psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +391 -0
- psychopy/demos/builder/Feature Demos/gratings/readme.md +8 -0
- psychopy/demos/builder/Feature Demos/movies/movie.psyexp +220 -0
- psychopy/demos/builder/Feature Demos/movies/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/noise/face.jpg +0 -0
- psychopy/demos/builder/Feature Demos/noise/noise.psyexp +477 -0
- psychopy/demos/builder/Feature Demos/noise/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/panorama/panImg.jpg +0 -0
- psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +177 -0
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +434 -0
- psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +451 -0
- psychopy/demos/builder/Feature Demos/progress/readme.md +1 -0
- psychopy/demos/builder/Feature Demos/sliders/README.md +8 -0
- psychopy/demos/builder/Feature Demos/sliders/fruitConditions.xlsx +0 -0
- psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +984 -0
- psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +199 -0
- psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +639 -0
- psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +415 -0
- psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +659 -0
- psychopy/demos/builder/Hardware/EGI_netstation/README.md +17 -0
- psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +339 -0
- psychopy/demos/builder/Hardware/EGI_netstation/trialTypesEEG.csv +7 -0
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/readme.md +19 -0
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/trials_params.xlsx +0 -0
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +830 -0
- psychopy/demos/builder/Hardware/camera/camera.psyexp +330 -0
- psychopy/demos/builder/Hardware/camera/readme.md +6 -0
- psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +459 -0
- psychopy/demos/builder/Hardware/eyetracking/readme.md +7 -0
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/Bullseye_grey.mov +0 -0
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +468 -0
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/readme.md +7 -0
- psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +211 -0
- psychopy/demos/builder/Hardware/fMRI/readme.md +7 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +484 -0
- psychopy/demos/builder/Hardware/microphone/phrases.xlsx +0 -0
- psychopy/demos/builder/Hardware/microphone/readme.md +9 -0
- psychopy/demos/builder/Hardware/pump/README.md +19 -0
- psychopy/demos/builder/Hardware/pump/pump.psyexp +646 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +350 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/readme.md +5 -0
- psychopy/demos/builder/Helper Tools/clockFace/README.md +3 -0
- psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +211 -0
- psychopy/demos/builder/Helper Tools/colors/README.md +5 -0
- psychopy/demos/builder/Helper Tools/colors/colors.psyexp +321 -0
- psychopy/demos/builder/Helper Tools/drawPolygon/README.md +5 -0
- psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +704 -0
- psychopy/demos/builder/Helper Tools/keyNameFinder/README.md +14 -0
- psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +225 -0
- psychopy/demos/builder/Helper Tools/spatialUnits/README.md +6 -0
- psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +206 -0
- psychopy/demos/builder/README.txt +43 -0
- psychopy/demos/builder/__init__.py +0 -0
- psychopy/demos/coder/__init__.py +0 -0
- psychopy/demos/coder/basic/hello_world.py +37 -0
- psychopy/demos/coder/csvFromPsydat.py +29 -0
- psychopy/demos/coder/experiment control/JND_staircase_analysis.py +85 -0
- psychopy/demos/coder/experiment control/JND_staircase_exp.py +110 -0
- psychopy/demos/coder/experiment control/TrialHandler.py +64 -0
- psychopy/demos/coder/experiment control/TrialHandler2.py +42 -0
- psychopy/demos/coder/experiment control/__init__.py +0 -0
- psychopy/demos/coder/experiment control/autoDraw_autoLog.py +50 -0
- psychopy/demos/coder/experiment control/experimentHandler.py +57 -0
- psychopy/demos/coder/experiment control/fMRI_launchScan.py +74 -0
- psychopy/demos/coder/experiment control/gammaMotionAnalysis.py +68 -0
- psychopy/demos/coder/experiment control/gammaMotionNull.py +169 -0
- psychopy/demos/coder/experiment control/logFiles.py +55 -0
- psychopy/demos/coder/experiment control/piloting.py +65 -0
- psychopy/demos/coder/experiment control/runtimeInfo.py +79 -0
- psychopy/demos/coder/hardware/CRS_BitsBox.py +75 -0
- psychopy/demos/coder/hardware/CRS_BitsPlusPlus.py +73 -0
- psychopy/demos/coder/hardware/RiftHeadTrackingExample.py +95 -0
- psychopy/demos/coder/hardware/RiftMinimal.py +44 -0
- psychopy/demos/coder/hardware/VSHD_Distortion.py +49 -0
- psychopy/demos/coder/hardware/__init__.py +0 -0
- psychopy/demos/coder/hardware/camera.py +90 -0
- psychopy/demos/coder/hardware/cedrusRB730.py +38 -0
- psychopy/demos/coder/hardware/crsBitsAdvancedDemo.py +780 -0
- psychopy/demos/coder/hardware/egi_netstation.py +45 -0
- psychopy/demos/coder/hardware/hdf5_extract.py +133 -0
- psychopy/demos/coder/hardware/ioLab_bbox.py +62 -0
- psychopy/demos/coder/hardware/labjack_u3.py +61 -0
- psychopy/demos/coder/hardware/monitorDemo.py +28 -0
- psychopy/demos/coder/hardware/parallelPortOutput.py +49 -0
- psychopy/demos/coder/hardware/qmixPump.py +79 -0
- psychopy/demos/coder/hardware/testSoundLatency.py +127 -0
- psychopy/demos/coder/input/GUI.py +52 -0
- psychopy/demos/coder/input/__init__.py +0 -0
- psychopy/demos/coder/input/customMouse.py +51 -0
- psychopy/demos/coder/input/joystick_universal.py +84 -0
- psychopy/demos/coder/input/keyNameFinder.py +39 -0
- psychopy/demos/coder/input/mic.png +0 -0
- psychopy/demos/coder/input/mouse.py +66 -0
- psychopy/demos/coder/iohub/delaytest.py +231 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/canal.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/fall.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/lake.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/party.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/images/swimming.jpg +0 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByConditionVariables.py +67 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/readTrialEventsByMessages.py +34 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/run.py +323 -0
- psychopy/demos/coder/iohub/eyetracking/gcCursor/trial_conditions.xlsx +0 -0
- psychopy/demos/coder/iohub/eyetracking/simple.py +147 -0
- psychopy/demos/coder/iohub/eyetracking/validation.py +251 -0
- psychopy/demos/coder/iohub/iodatastore/saveEventReport.py +56 -0
- psychopy/demos/coder/iohub/keyboard.py +189 -0
- psychopy/demos/coder/iohub/keyboardreactiontime.py +88 -0
- psychopy/demos/coder/iohub/launchHub.py +160 -0
- psychopy/demos/coder/iohub/mouse.py +112 -0
- psychopy/demos/coder/iohub/mouse_multi_window.py +124 -0
- psychopy/demos/coder/iohub/serial/_parseserial.py +53 -0
- psychopy/demos/coder/iohub/serial/customparser.py +84 -0
- psychopy/demos/coder/iohub/serial/pstbox.py +166 -0
- psychopy/demos/coder/iohub/wintab/_wintabgraphics.py +281 -0
- psychopy/demos/coder/iohub/wintab/pen_demo.py +260 -0
- psychopy/demos/coder/misc/encrypt_data.py +48 -0
- psychopy/demos/coder/misc/hdf5_2_csv +33 -0
- psychopy/demos/coder/misc/makeMovie.py +28 -0
- psychopy/demos/coder/misc/rigidBodyTransform.py +76 -0
- psychopy/demos/coder/stimuli/Campaign.ttf +0 -0
- psychopy/demos/coder/stimuli/MovieStim.py +65 -0
- psychopy/demos/coder/stimuli/__init__.py +0 -0
- psychopy/demos/coder/stimuli/aperture.py +37 -0
- psychopy/demos/coder/stimuli/beach.jpg +0 -0
- psychopy/demos/coder/stimuli/bufferImageStim.py +78 -0
- psychopy/demos/coder/stimuli/clockface.py +43 -0
- psychopy/demos/coder/stimuli/colorPalette.py +134 -0
- psychopy/demos/coder/stimuli/compare_text_timing.py +193 -0
- psychopy/demos/coder/stimuli/counterphase.py +43 -0
- psychopy/demos/coder/stimuli/customTextures.py +57 -0
- psychopy/demos/coder/stimuli/dot_gabors.py +35 -0
- psychopy/demos/coder/stimuli/dots.py +35 -0
- psychopy/demos/coder/stimuli/elementArrays.py +92 -0
- psychopy/demos/coder/stimuli/embeddedOpenGL.py +35 -0
- psychopy/demos/coder/stimuli/face.jpg +0 -0
- psychopy/demos/coder/stimuli/face_jpg.py +48 -0
- psychopy/demos/coder/stimuli/gabor.py +30 -0
- psychopy/demos/coder/stimuli/imagesAndPatches.py +51 -0
- psychopy/demos/coder/stimuli/jwpIntro.mp4 +0 -0
- psychopy/demos/coder/stimuli/kanizsa.py +41 -0
- psychopy/demos/coder/stimuli/maskReveal.py +63 -0
- psychopy/demos/coder/stimuli/plaid.py +43 -0
- psychopy/demos/coder/stimuli/ratingScale.py +183 -0
- psychopy/demos/coder/stimuli/rotatingFlashingWedge.py +37 -0
- psychopy/demos/coder/stimuli/screensAndWindows.py +58 -0
- psychopy/demos/coder/stimuli/secondOrderGratings.py +66 -0
- psychopy/demos/coder/stimuli/shapeContains.py +50 -0
- psychopy/demos/coder/stimuli/shapes.py +63 -0
- psychopy/demos/coder/stimuli/soundStimuli.py +49 -0
- psychopy/demos/coder/stimuli/starField.py +48 -0
- psychopy/demos/coder/stimuli/stim3d.py +107 -0
- psychopy/demos/coder/stimuli/textBoxStim/textbox_glyph_placement.py +93 -0
- psychopy/demos/coder/stimuli/textBoxStim/textbox_simple.py +71 -0
- psychopy/demos/coder/stimuli/textStimuli.py +106 -0
- psychopy/demos/coder/stimuli/textbox_editable.py +64 -0
- psychopy/demos/coder/stimuli/variousVisualStims.py +47 -0
- psychopy/demos/coder/stimuli/visual_noise.py +31 -0
- psychopy/demos/coder/sysInfo.py +56 -0
- psychopy/demos/coder/timing/__init__.py +0 -0
- psychopy/demos/coder/timing/callOnFlip.py +39 -0
- psychopy/demos/coder/timing/clocksAndTimers.py +46 -0
- psychopy/demos/coder/timing/millikeyKeyboardTimingTest.py +323 -0
- psychopy/demos/coder/timing/timeByFrames.py +80 -0
- psychopy/demos/coder/timing/timeByFramesEx.py +107 -0
- psychopy/demos/coder/understanding psychopy/colors.py +70 -0
- psychopy/demos/coder/understanding psychopy/fontLayout.py +69 -0
- psychopy/demos/demo_migration.py +214 -0
- psychopy/demos/modernizeDemos.py +16 -0
- psychopy/demos/test_demo_migration.py +155 -0
- psychopy/devices/__init__.py +8 -0
- psychopy/event.py +1339 -0
- psychopy/exceptions.py +59 -0
- psychopy/experiment/__init__.py +51 -0
- psychopy/experiment/_experiment.py +1514 -0
- psychopy/experiment/blankTemplate.xltx +0 -0
- psychopy/experiment/components/__init__.py +402 -0
- psychopy/experiment/components/_base.py +1689 -0
- psychopy/experiment/components/aperture/__init__.py +153 -0
- psychopy/experiment/components/aperture/classic/aperture.png +0 -0
- psychopy/experiment/components/aperture/classic/aperture@2x.png +0 -0
- psychopy/experiment/components/aperture/dark/aperture.png +0 -0
- psychopy/experiment/components/aperture/dark/aperture@2x.png +0 -0
- psychopy/experiment/components/aperture/light/aperture.png +0 -0
- psychopy/experiment/components/aperture/light/aperture@2x.png +0 -0
- psychopy/experiment/components/brush/__init__.py +165 -0
- psychopy/experiment/components/brush/classic/brush.png +0 -0
- psychopy/experiment/components/brush/classic/brush@2x.png +0 -0
- psychopy/experiment/components/brush/dark/brush.png +0 -0
- psychopy/experiment/components/brush/dark/brush@2x.png +0 -0
- psychopy/experiment/components/brush/light/brush.png +0 -0
- psychopy/experiment/components/brush/light/brush@2x.png +0 -0
- psychopy/experiment/components/button/__init__.py +493 -0
- psychopy/experiment/components/button/classic/button.png +0 -0
- psychopy/experiment/components/button/classic/button@2x.png +0 -0
- psychopy/experiment/components/button/dark/button.png +0 -0
- psychopy/experiment/components/button/dark/button@2x.png +0 -0
- psychopy/experiment/components/button/light/button.png +0 -0
- psychopy/experiment/components/button/light/button@2x.png +0 -0
- psychopy/experiment/components/buttonBox/__init__.py +322 -0
- psychopy/experiment/components/buttonBox/classic/buttonBox.png +0 -0
- psychopy/experiment/components/buttonBox/classic/buttonBox@2x.png +0 -0
- psychopy/experiment/components/buttonBox/dark/buttonBox.png +0 -0
- psychopy/experiment/components/buttonBox/dark/buttonBox@2x.png +0 -0
- psychopy/experiment/components/buttonBox/light/buttonBox.png +0 -0
- psychopy/experiment/components/buttonBox/light/buttonBox@2x.png +0 -0
- psychopy/experiment/components/camera/__init__.py +381 -0
- psychopy/experiment/components/camera/classic/webcam.png +0 -0
- psychopy/experiment/components/camera/classic/webcam@2x.png +0 -0
- psychopy/experiment/components/camera/dark/webcam.png +0 -0
- psychopy/experiment/components/camera/dark/webcam@2x.png +0 -0
- psychopy/experiment/components/camera/light/webcam.png +0 -0
- psychopy/experiment/components/camera/light/webcam@2x.png +0 -0
- psychopy/experiment/components/code/__init__.py +299 -0
- psychopy/experiment/components/code/classic/code.png +0 -0
- psychopy/experiment/components/code/classic/code@2x.png +0 -0
- psychopy/experiment/components/code/dark/code.png +0 -0
- psychopy/experiment/components/code/dark/code@2x.png +0 -0
- psychopy/experiment/components/code/light/code.png +0 -0
- psychopy/experiment/components/code/light/code@2x.png +0 -0
- psychopy/experiment/components/dots/__init__.py +199 -0
- psychopy/experiment/components/dots/classic/dots.png +0 -0
- psychopy/experiment/components/dots/classic/dots@2x.png +0 -0
- psychopy/experiment/components/dots/dark/dots.png +0 -0
- psychopy/experiment/components/dots/dark/dots@2x.png +0 -0
- psychopy/experiment/components/dots/dots.xcf +0 -0
- psychopy/experiment/components/dots/light/dots.png +0 -0
- psychopy/experiment/components/dots/light/dots@2x.png +0 -0
- psychopy/experiment/components/eyetracker_record/__init__.py +194 -0
- psychopy/experiment/components/eyetracker_record/classic/eyetracker_record.png +0 -0
- psychopy/experiment/components/eyetracker_record/classic/eyetracker_record@2x.png +0 -0
- psychopy/experiment/components/eyetracker_record/dark/eyetracker_record.png +0 -0
- psychopy/experiment/components/eyetracker_record/dark/eyetracker_record@2x.png +0 -0
- psychopy/experiment/components/eyetracker_record/light/eyetracker_record.png +0 -0
- psychopy/experiment/components/eyetracker_record/light/eyetracker_record@2x.png +0 -0
- psychopy/experiment/components/form/__init__.py +227 -0
- psychopy/experiment/components/form/classic/form.png +0 -0
- psychopy/experiment/components/form/classic/form@2x.png +0 -0
- psychopy/experiment/components/form/dark/form.png +0 -0
- psychopy/experiment/components/form/dark/form@2x.png +0 -0
- psychopy/experiment/components/form/formItems.xltx +0 -0
- psychopy/experiment/components/form/light/form.png +0 -0
- psychopy/experiment/components/form/light/form@2x.png +0 -0
- psychopy/experiment/components/grating/__init__.py +203 -0
- psychopy/experiment/components/grating/classic/grating.png +0 -0
- psychopy/experiment/components/grating/classic/grating@2x.png +0 -0
- psychopy/experiment/components/grating/dark/grating.png +0 -0
- psychopy/experiment/components/grating/dark/grating@2x.png +0 -0
- psychopy/experiment/components/grating/light/grating.png +0 -0
- psychopy/experiment/components/grating/light/grating@2x.png +0 -0
- psychopy/experiment/components/image/__init__.py +195 -0
- psychopy/experiment/components/image/classic/image.png +0 -0
- psychopy/experiment/components/image/classic/image@2x.png +0 -0
- psychopy/experiment/components/image/dark/image.png +0 -0
- psychopy/experiment/components/image/dark/image@2x.png +0 -0
- psychopy/experiment/components/image/light/image.png +0 -0
- psychopy/experiment/components/image/light/image@2x.png +0 -0
- psychopy/experiment/components/joyButtons/__init__.py +453 -0
- psychopy/experiment/components/joyButtons/classic/joyButtons.png +0 -0
- psychopy/experiment/components/joyButtons/classic/joybuttons@2x.png +0 -0
- psychopy/experiment/components/joyButtons/dark/joyButtons.png +0 -0
- psychopy/experiment/components/joyButtons/dark/joyButtons@2x.png +0 -0
- psychopy/experiment/components/joyButtons/light/joyButtons.png +0 -0
- psychopy/experiment/components/joyButtons/light/joyButtons@2x.png +0 -0
- psychopy/experiment/components/joyButtons/virtualJoyButtons.py +34 -0
- psychopy/experiment/components/joystick/__init__.py +572 -0
- psychopy/experiment/components/joystick/classic/joystick.png +0 -0
- psychopy/experiment/components/joystick/classic/joystick@2x.png +0 -0
- psychopy/experiment/components/joystick/dark/joystick.png +0 -0
- psychopy/experiment/components/joystick/dark/joystick@2x.png +0 -0
- psychopy/experiment/components/joystick/light/joystick.png +0 -0
- psychopy/experiment/components/joystick/light/joystick@2x.png +0 -0
- psychopy/experiment/components/joystick/virtualJoystick.py +40 -0
- psychopy/experiment/components/keyboard/__init__.py +568 -0
- psychopy/experiment/components/keyboard/classic/keyboard.png +0 -0
- psychopy/experiment/components/keyboard/classic/keyboard@2x.png +0 -0
- psychopy/experiment/components/keyboard/dark/keyboard.png +0 -0
- psychopy/experiment/components/keyboard/dark/keyboard@2x.png +0 -0
- psychopy/experiment/components/keyboard/light/keyboard.png +0 -0
- psychopy/experiment/components/keyboard/light/keyboard@2x.png +0 -0
- psychopy/experiment/components/keyboard.xcf +0 -0
- psychopy/experiment/components/microphone/__init__.py +600 -0
- psychopy/experiment/components/microphone/classic/microphone.png +0 -0
- psychopy/experiment/components/microphone/classic/microphone@2x.png +0 -0
- psychopy/experiment/components/microphone/dark/microphone.png +0 -0
- psychopy/experiment/components/microphone/dark/microphone@2x.png +0 -0
- psychopy/experiment/components/microphone/light/microphone.png +0 -0
- psychopy/experiment/components/microphone/light/microphone@2x.png +0 -0
- psychopy/experiment/components/mouse/__init__.py +773 -0
- psychopy/experiment/components/mouse/classic/mouse.png +0 -0
- psychopy/experiment/components/mouse/classic/mouse@2x.png +0 -0
- psychopy/experiment/components/mouse/dark/mouse.png +0 -0
- psychopy/experiment/components/mouse/dark/mouse@2x.png +0 -0
- psychopy/experiment/components/mouse/light/mouse.png +0 -0
- psychopy/experiment/components/mouse/light/mouse@2x.png +0 -0
- psychopy/experiment/components/movie/__init__.py +348 -0
- psychopy/experiment/components/movie/classic/movie.png +0 -0
- psychopy/experiment/components/movie/classic/movie@2x.png +0 -0
- psychopy/experiment/components/movie/dark/movie.png +0 -0
- psychopy/experiment/components/movie/dark/movie@2x.png +0 -0
- psychopy/experiment/components/movie/light/movie.png +0 -0
- psychopy/experiment/components/movie/light/movie@2x.png +0 -0
- psychopy/experiment/components/panorama/__init__.py +456 -0
- psychopy/experiment/components/panorama/classic/panorama.png +0 -0
- psychopy/experiment/components/panorama/classic/panorama@2x.png +0 -0
- psychopy/experiment/components/panorama/dark/panorama.png +0 -0
- psychopy/experiment/components/panorama/dark/panorama@2x.png +0 -0
- psychopy/experiment/components/panorama/light/panorama.png +0 -0
- psychopy/experiment/components/panorama/light/panorama@2x.png +0 -0
- psychopy/experiment/components/parallelOut/__init__.py +178 -0
- psychopy/experiment/components/parallelOut/classic/parallel.png +0 -0
- psychopy/experiment/components/parallelOut/classic/parallel@2x.png +0 -0
- psychopy/experiment/components/parallelOut/dark/parallel.png +0 -0
- psychopy/experiment/components/parallelOut/dark/parallel@2x.png +0 -0
- psychopy/experiment/components/parallelOut/light/parallel.png +0 -0
- psychopy/experiment/components/parallelOut/light/parallel@2x.png +0 -0
- psychopy/experiment/components/polygon/__init__.py +332 -0
- psychopy/experiment/components/polygon/classic/polygon.png +0 -0
- psychopy/experiment/components/polygon/classic/polygon@2x.png +0 -0
- psychopy/experiment/components/polygon/dark/polygon.png +0 -0
- psychopy/experiment/components/polygon/dark/polygon@2x.png +0 -0
- psychopy/experiment/components/polygon/light/polygon.png +0 -0
- psychopy/experiment/components/polygon/light/polygon@2x.png +0 -0
- psychopy/experiment/components/progress/__init__.py +130 -0
- psychopy/experiment/components/progress/classic/progress.png +0 -0
- psychopy/experiment/components/progress/classic/progress@2x.png +0 -0
- psychopy/experiment/components/progress/dark/progress.png +0 -0
- psychopy/experiment/components/progress/dark/progress@2x.png +0 -0
- psychopy/experiment/components/progress/light/progress.png +0 -0
- psychopy/experiment/components/progress/light/progress@2x.png +0 -0
- psychopy/experiment/components/resourceManager/__init__.py +176 -0
- psychopy/experiment/components/resourceManager/classic/resource_manager.png +0 -0
- psychopy/experiment/components/resourceManager/classic/resource_manager@2x.png +0 -0
- psychopy/experiment/components/resourceManager/dark/resource_manager.png +0 -0
- psychopy/experiment/components/resourceManager/dark/resource_manager@2x.png +0 -0
- psychopy/experiment/components/resourceManager/light/resource_manager.png +0 -0
- psychopy/experiment/components/resourceManager/light/resource_manager@2x.png +0 -0
- psychopy/experiment/components/roi/__init__.py +316 -0
- psychopy/experiment/components/roi/classic/eyetracker_roi.png +0 -0
- psychopy/experiment/components/roi/classic/eyetracker_roi@2x.png +0 -0
- psychopy/experiment/components/roi/dark/eyetracker_roi.png +0 -0
- psychopy/experiment/components/roi/dark/eyetracker_roi@2X.png +0 -0
- psychopy/experiment/components/roi/light/eyetracker_roi.png +0 -0
- psychopy/experiment/components/roi/light/eyetracker_roi@2X.png +0 -0
- psychopy/experiment/components/routineSettings/__init__.py +387 -0
- psychopy/experiment/components/routineSettings/classic/routineSettings.png +0 -0
- psychopy/experiment/components/routineSettings/classic/routineSettings@2x.png +0 -0
- psychopy/experiment/components/routineSettings/dark/routineSettings.png +0 -0
- psychopy/experiment/components/routineSettings/dark/routineSettings@2x.png +0 -0
- psychopy/experiment/components/routineSettings/light/routineSettings.png +0 -0
- psychopy/experiment/components/routineSettings/light/routineSettings@2x.png +0 -0
- psychopy/experiment/components/serialOut/__init__.py +304 -0
- psychopy/experiment/components/serialOut/classic/serial.png +0 -0
- psychopy/experiment/components/serialOut/classic/serial@2x.png +0 -0
- psychopy/experiment/components/serialOut/dark/serial.png +0 -0
- psychopy/experiment/components/serialOut/dark/serial@2x.png +0 -0
- psychopy/experiment/components/serialOut/light/serial.png +0 -0
- psychopy/experiment/components/serialOut/light/serial@2x.png +0 -0
- psychopy/experiment/components/settings/JS_htmlHeader.tmpl +23 -0
- psychopy/experiment/components/settings/JS_setupExp.tmpl +28 -0
- psychopy/experiment/components/settings/__init__.py +2254 -0
- psychopy/experiment/components/settings/classic/settings.png +0 -0
- psychopy/experiment/components/settings/classic/settings@2x.png +0 -0
- psychopy/experiment/components/settings/dark/settings.png +0 -0
- psychopy/experiment/components/settings/dark/settings@2x.png +0 -0
- psychopy/experiment/components/settings/eyetracking.py +108 -0
- psychopy/experiment/components/settings/light/settings.png +0 -0
- psychopy/experiment/components/settings/light/settings@2x.png +0 -0
- psychopy/experiment/components/slider/__init__.py +410 -0
- psychopy/experiment/components/slider/classic/slider.png +0 -0
- psychopy/experiment/components/slider/classic/slider@2x.png +0 -0
- psychopy/experiment/components/slider/dark/slider.png +0 -0
- psychopy/experiment/components/slider/dark/slider@2x.png +0 -0
- psychopy/experiment/components/slider/light/slider.png +0 -0
- psychopy/experiment/components/slider/light/slider@2x.png +0 -0
- psychopy/experiment/components/sound/__init__.py +441 -0
- psychopy/experiment/components/sound/classic/sound.png +0 -0
- psychopy/experiment/components/sound/classic/sound@2x.png +0 -0
- psychopy/experiment/components/sound/dark/sound.png +0 -0
- psychopy/experiment/components/sound/dark/sound@2x.png +0 -0
- psychopy/experiment/components/sound/light/sound.png +0 -0
- psychopy/experiment/components/sound/light/sound@2x.png +0 -0
- psychopy/experiment/components/soundsensor/__init__.py +324 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
- psychopy/experiment/components/static/__init__.py +293 -0
- psychopy/experiment/components/static/classic/static.png +0 -0
- psychopy/experiment/components/static/classic/static@2x.png +0 -0
- psychopy/experiment/components/static/dark/static.png +0 -0
- psychopy/experiment/components/static/dark/static@2x.png +0 -0
- psychopy/experiment/components/static/light/static.png +0 -0
- psychopy/experiment/components/static/light/static@2x.png +0 -0
- psychopy/experiment/components/text/__init__.py +190 -0
- psychopy/experiment/components/text/classic/text.png +0 -0
- psychopy/experiment/components/text/classic/text@2x.png +0 -0
- psychopy/experiment/components/text/dark/text.png +0 -0
- psychopy/experiment/components/text/dark/text@2x.png +0 -0
- psychopy/experiment/components/text/light/text.png +0 -0
- psychopy/experiment/components/text/light/text@2x.png +0 -0
- psychopy/experiment/components/textbox/__init__.py +336 -0
- psychopy/experiment/components/textbox/classic/textbox.png +0 -0
- psychopy/experiment/components/textbox/classic/textbox@2x.png +0 -0
- psychopy/experiment/components/textbox/dark/textbox.png +0 -0
- psychopy/experiment/components/textbox/dark/textbox@2x.png +0 -0
- psychopy/experiment/components/textbox/light/textbox.png +0 -0
- psychopy/experiment/components/textbox/light/textbox@2x.png +0 -0
- psychopy/experiment/components/unknown/__init__.py +87 -0
- psychopy/experiment/components/unknown/classic/unknown.png +0 -0
- psychopy/experiment/components/unknown/classic/unknown@2x.png +0 -0
- psychopy/experiment/components/unknown/dark/unknown.png +0 -0
- psychopy/experiment/components/unknown/dark/unknown@2x.png +0 -0
- psychopy/experiment/components/unknown/light/unknown.png +0 -0
- psychopy/experiment/components/unknown/light/unknown@2x.png +0 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +86 -0
- psychopy/experiment/components/unknownPlugin/classic/unknownPlugin.png +0 -0
- psychopy/experiment/components/unknownPlugin/classic/unknownPlugin@2x.png +0 -0
- psychopy/experiment/components/unknownPlugin/dark/unknownPlugin.png +0 -0
- psychopy/experiment/components/unknownPlugin/dark/unknownPlugin@2x.png +0 -0
- psychopy/experiment/components/unknownPlugin/light/unknownPlugin.png +0 -0
- psychopy/experiment/components/unknownPlugin/light/unknownPlugin@2x.png +0 -0
- psychopy/experiment/components/utils.py +0 -0
- psychopy/experiment/components/variable/__init__.py +184 -0
- psychopy/experiment/components/variable/classic/variable.png +0 -0
- psychopy/experiment/components/variable/classic/variable@2x.png +0 -0
- psychopy/experiment/components/variable/dark/variable.png +0 -0
- psychopy/experiment/components/variable/dark/variable@2x.png +0 -0
- psychopy/experiment/components/variable/light/variable.png +0 -0
- psychopy/experiment/components/variable/light/variable@2x.png +0 -0
- psychopy/experiment/devices.py +303 -0
- psychopy/experiment/experiment.xsd +223 -0
- psychopy/experiment/exports.py +390 -0
- psychopy/experiment/flow.py +547 -0
- psychopy/experiment/localization.py +11 -0
- psychopy/experiment/loopTemplate.xltx +0 -0
- psychopy/experiment/loops.py +1051 -0
- psychopy/experiment/monitor.py +74 -0
- psychopy/experiment/params.py +541 -0
- psychopy/experiment/plugins.py +42 -0
- psychopy/experiment/py2js.py +183 -0
- psychopy/experiment/py2js_transpiler.py +613 -0
- psychopy/experiment/questPlusTemplate.xltx +0 -0
- psychopy/experiment/questTemplate.xltx +0 -0
- psychopy/experiment/routines/__init__.py +108 -0
- psychopy/experiment/routines/_base.py +1172 -0
- psychopy/experiment/routines/audioValidator/__init__.py +229 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/counterbalance/__init__.py +320 -0
- psychopy/experiment/routines/counterbalance/classic/counterbalance.png +0 -0
- psychopy/experiment/routines/counterbalance/classic/counterbalance@2x.png +0 -0
- psychopy/experiment/routines/counterbalance/counterbalanceItems.xltx +0 -0
- psychopy/experiment/routines/counterbalance/dark/counterbalance.png +0 -0
- psychopy/experiment/routines/counterbalance/dark/counterbalance@2x.png +0 -0
- psychopy/experiment/routines/counterbalance/light/counterbalance.png +0 -0
- psychopy/experiment/routines/counterbalance/light/counterbalance@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/__init__.py +334 -0
- psychopy/experiment/routines/eyetracker_calibrate/classic/eyetracker_calib.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/dark/eyetracker_calib@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/light/eyetracker_calib@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/__init__.py +354 -0
- psychopy/experiment/routines/eyetracker_validate/classic/eyetracker_valid.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/dark/eyetracker_valid@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid.png +0 -0
- psychopy/experiment/routines/eyetracker_validate/light/eyetracker_valid@2x.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/__init__.py +236 -0
- psychopy/experiment/routines/pavlovia_survey/classic/survey.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/classic/survey@2x.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/dark/survey.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/dark/survey@2x.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/light/survey.png +0 -0
- psychopy/experiment/routines/pavlovia_survey/light/survey@2x.png +0 -0
- psychopy/experiment/routines/unknown/__init__.py +30 -0
- psychopy/experiment/routines/unknown/classic/eyetracker_record.png +0 -0
- psychopy/experiment/routines/unknown/classic/unknown.png +0 -0
- psychopy/experiment/routines/unknown/dark/eyetracker_record.png +0 -0
- psychopy/experiment/routines/unknown/dark/eyetracker_record@2x.png +0 -0
- psychopy/experiment/routines/unknown/dark/unknown.png +0 -0
- psychopy/experiment/routines/unknown/dark/unknown@2x.png +0 -0
- psychopy/experiment/routines/unknown/light/eyetracker_record.png +0 -0
- psychopy/experiment/routines/unknown/light/eyetracker_record@2x.png +0 -0
- psychopy/experiment/routines/unknown/light/unknown.png +0 -0
- psychopy/experiment/routines/unknown/light/unknown@2x.png +0 -0
- psychopy/experiment/routines/utils.py +0 -0
- psychopy/experiment/routines/visualValidator/__init__.py +395 -0
- psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
- psychopy/experiment/staircaseTemplate.xltx +0 -0
- psychopy/experiment/utils.py +44 -0
- psychopy/filters.py +11 -0
- psychopy/gamma.py +9 -0
- psychopy/gui/__init__.py +47 -0
- psychopy/gui/qtgui.py +882 -0
- psychopy/gui/util.py +74 -0
- psychopy/gui/wxgui.py +420 -0
- psychopy/hardware/__init__.py +178 -0
- psychopy/hardware/base.py +466 -0
- psychopy/hardware/bbtk/__init__.py +24 -0
- psychopy/hardware/brainproducts.py +25 -0
- psychopy/hardware/button.py +238 -0
- psychopy/hardware/buttonbox/__init__.py +122 -0
- psychopy/hardware/camera/__init__.py +3657 -0
- psychopy/hardware/cedrus.py +24 -0
- psychopy/hardware/crs/__init__.py +46 -0
- psychopy/hardware/crs/bits.py +37 -0
- psychopy/hardware/crs/colorcal.py +18 -0
- psychopy/hardware/crs/optical.py +33 -0
- psychopy/hardware/crs/shaders.py +34 -0
- psychopy/hardware/emotiv.py +33 -0
- psychopy/hardware/emulator.py +46 -0
- psychopy/hardware/exceptions.py +86 -0
- psychopy/hardware/eyetracker.py +132 -0
- psychopy/hardware/forp.py +37 -0
- psychopy/hardware/gammasci.py +26 -0
- psychopy/hardware/iolab.py +24 -0
- psychopy/hardware/joystick/__init__.py +1196 -0
- psychopy/hardware/joystick/_base.py +251 -0
- psychopy/hardware/joystick/backend_glfw.py +306 -0
- psychopy/hardware/joystick/backend_pyglet.py +309 -0
- psychopy/hardware/joystick/mappings.py +287 -0
- psychopy/hardware/keyboard.py +975 -0
- psychopy/hardware/knownDevices.json +52 -0
- psychopy/hardware/labhackers.py +27 -0
- psychopy/hardware/labjacks.py +26 -0
- psychopy/hardware/lightsensor.py +789 -0
- psychopy/hardware/listener.py +330 -0
- psychopy/hardware/manager.py +992 -0
- psychopy/hardware/microphone.py +1630 -0
- psychopy/hardware/minolta.py +33 -0
- psychopy/hardware/monitor.py +144 -0
- psychopy/hardware/mouse/__init__.py +885 -0
- psychopy/hardware/photometer/__init__.py +207 -0
- psychopy/hardware/pr.py +33 -0
- psychopy/hardware/qmix.py +32 -0
- psychopy/hardware/serialdevice.py +387 -0
- psychopy/hardware/soundsensor.py +476 -0
- psychopy/hardware/spatial/__init__.py +231 -0
- psychopy/hardware/speaker.py +351 -0
- psychopy/hardware/triggerbox/__init__.py +56 -0
- psychopy/hardware/triggerbox/base.py +170 -0
- psychopy/hardware/triggerbox/parallel.py +362 -0
- psychopy/info.py +719 -0
- psychopy/iohub/__init__.py +50 -0
- psychopy/iohub/client/__init__.py +1481 -0
- psychopy/iohub/client/connect.py +260 -0
- psychopy/iohub/client/eyetracker/__init__.py +4 -0
- psychopy/iohub/client/eyetracker/validation/__init__.py +8 -0
- psychopy/iohub/client/eyetracker/validation/posgrid.py +274 -0
- psychopy/iohub/client/eyetracker/validation/procedure.py +1292 -0
- psychopy/iohub/client/eyetracker/validation/trigger.py +240 -0
- psychopy/iohub/client/keyboard.py +513 -0
- psychopy/iohub/client/wintab.py +378 -0
- psychopy/iohub/constants.py +1176 -0
- psychopy/iohub/datastore/__init__.py +439 -0
- psychopy/iohub/datastore/default_datastore.yaml +8 -0
- psychopy/iohub/datastore/util.py +868 -0
- psychopy/iohub/default_config.yaml +17 -0
- psychopy/iohub/devices/__init__.py +1047 -0
- psychopy/iohub/devices/computer.py +607 -0
- psychopy/iohub/devices/default_device.yaml +15 -0
- psychopy/iohub/devices/deviceConfigValidation.py +519 -0
- psychopy/iohub/devices/display/__init__.py +755 -0
- psychopy/iohub/devices/display/default_display.yaml +118 -0
- psychopy/iohub/devices/display/supported_config_settings.yaml +69 -0
- psychopy/iohub/devices/eventfilters.py +3572 -0
- psychopy/iohub/devices/experiment/__init__.py +316 -0
- psychopy/iohub/devices/experiment/default_experiment.yaml +74 -0
- psychopy/iohub/devices/experiment/supported_config_settings.yaml +26 -0
- psychopy/iohub/devices/eyetracker/__init__.py +474 -0
- psychopy/iohub/devices/eyetracker/calibration/__init__.py +1 -0
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +391 -0
- psychopy/iohub/devices/eyetracker/default_eyetracker.yaml +18 -0
- psychopy/iohub/devices/eyetracker/eye_events.py +1751 -0
- psychopy/iohub/devices/eyetracker/filters/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/filters/parser.py +913 -0
- psychopy/iohub/devices/eyetracker/hw/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/calibration.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +31 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/__init__.py +8 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/calibration.py +10 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/default_eyetracker.yaml +102 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +443 -0
- psychopy/iohub/devices/eyetracker/hw/mouse/supported_config_settings.yaml +110 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +27 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/eyetracker.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/bisector.py +20 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/constants.py +19 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/data_parse.py +22 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/eyetracker.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/pupil_core/pupil_remote.py +18 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/__init__.py +4 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/__init__.py +28 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/calibration.py +22 -0
- psychopy/iohub/devices/eyetracker/hw/sr_research/eyelink/eyetracker.py +38 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/__init__.py +29 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/calibration.py +19 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/eyetracker.py +17 -0
- psychopy/iohub/devices/eyetracker/hw/tobii/tobiiwrapper.py +19 -0
- psychopy/iohub/devices/eyetracker/supported_config_settings.yaml +44 -0
- psychopy/iohub/devices/keyboard/__init__.py +309 -0
- psychopy/iohub/devices/keyboard/darwin.py +431 -0
- psychopy/iohub/devices/keyboard/darwinkey.py +94 -0
- psychopy/iohub/devices/keyboard/default_keyboard.yaml +94 -0
- psychopy/iohub/devices/keyboard/linux2.py +102 -0
- psychopy/iohub/devices/keyboard/supported_config_settings.yaml +39 -0
- psychopy/iohub/devices/keyboard/win32.py +356 -0
- psychopy/iohub/devices/mouse/__init__.py +709 -0
- psychopy/iohub/devices/mouse/darwin.py +414 -0
- psychopy/iohub/devices/mouse/default_mouse.yaml +92 -0
- psychopy/iohub/devices/mouse/linux2.py +172 -0
- psychopy/iohub/devices/mouse/supported_config_settings.yaml +39 -0
- psychopy/iohub/devices/mouse/win32.py +284 -0
- psychopy/iohub/devices/pyXHook.py +619 -0
- psychopy/iohub/devices/serial/__init__.py +779 -0
- psychopy/iohub/devices/serial/default_pstbox.yaml +108 -0
- psychopy/iohub/devices/serial/default_serial.yaml +108 -0
- psychopy/iohub/devices/serial/supported_config_settings.yaml +85 -0
- psychopy/iohub/devices/serial/supported_config_settings_pstbox.yaml +85 -0
- psychopy/iohub/devices/supported_config_settings.yaml +36 -0
- psychopy/iohub/devices/wintab/__init__.py +580 -0
- psychopy/iohub/devices/wintab/default_wintab.yaml +89 -0
- psychopy/iohub/devices/wintab/supported_config_settings.yaml +42 -0
- psychopy/iohub/devices/wintab/win32.py +722 -0
- psychopy/iohub/devices/xlib.py +6795 -0
- psychopy/iohub/errors.py +61 -0
- psychopy/iohub/lazy_import.py +582 -0
- psychopy/iohub/net.py +349 -0
- psychopy/iohub/server.py +1075 -0
- psychopy/iohub/start_iohub_process.py +121 -0
- psychopy/iohub/util/__init__.py +832 -0
- psychopy/iohub/util/visualangle.py +126 -0
- psychopy/layout.py +916 -0
- psychopy/liaison.py +471 -0
- psychopy/locale_setup.py +41 -0
- psychopy/localization/__init__.py +22 -0
- psychopy/localization/_localization.py +155 -0
- psychopy/localization/generateTranslationTemplate.py +257 -0
- psychopy/localization/mappings.txt +170 -0
- psychopy/localization/messages.pot +9950 -0
- psychopy/localization/readme.txt +68 -0
- psychopy/logging.py +415 -0
- psychopy/microphone.py +28 -0
- psychopy/misc.py +40 -0
- psychopy/monitors/MonitorCenter.py +1354 -0
- psychopy/monitors/__init__.py +30 -0
- psychopy/monitors/calibData.py +78 -0
- psychopy/monitors/calibTools.py +1301 -0
- psychopy/monitors/getLumSeries.py +50 -0
- psychopy/monitors/psychopy-icon.svg +395 -0
- psychopy/monitors/psychopy.ico +0 -0
- psychopy/parallel/__init__.py +206 -0
- psychopy/parallel/_dlportio.py +150 -0
- psychopy/parallel/_inpout.py +120 -0
- psychopy/parallel/_linux.py +105 -0
- psychopy/piloting.py +61 -0
- psychopy/platform_specific/__init__.py +46 -0
- psychopy/platform_specific/darwin.py +326 -0
- psychopy/platform_specific/linux.py +77 -0
- psychopy/platform_specific/win32.py +124 -0
- psychopy/plugins/__init__.py +1397 -0
- psychopy/plugins/util.py +104 -0
- psychopy/preferences/Darwin.spec +294 -0
- psychopy/preferences/FreeBSD.spec +294 -0
- psychopy/preferences/Linux.spec +294 -0
- psychopy/preferences/Windows.spec +294 -0
- psychopy/preferences/__init__.py +20 -0
- psychopy/preferences/baseNoArch.spec +290 -0
- psychopy/preferences/devices.py +80 -0
- psychopy/preferences/generateHints.py +93 -0
- psychopy/preferences/generateSpec.py +80 -0
- psychopy/preferences/hints.py +367 -0
- psychopy/preferences/preferences.py +448 -0
- psychopy/projects/__init__.py +11 -0
- psychopy/projects/gitignore.py +45 -0
- psychopy/projects/pavlovia.py +1674 -0
- psychopy/projects/sshkeys.py +107 -0
- psychopy/psychojs.zip +0 -0
- psychopy/pylintrc +69 -0
- psychopy/scripts/__init__.py +0 -0
- psychopy/scripts/psychopy-pkgutil.py +969 -0
- psychopy/scripts/psyexpCompile.py +229 -0
- psychopy/session.py +1651 -0
- psychopy/sound/__init__.py +50 -0
- psychopy/sound/_base.py +399 -0
- psychopy/sound/audioclip.py +1325 -0
- psychopy/sound/audiodevice.py +857 -0
- psychopy/sound/backend_ptb.py +406 -0
- psychopy/sound/backend_pygame.py +323 -0
- psychopy/sound/backend_pyo.py +64 -0
- psychopy/sound/backend_pysound.py +324 -0
- psychopy/sound/backend_sounddevice.py +44 -0
- psychopy/sound/backends/__init__.py +0 -0
- psychopy/sound/exceptions.py +115 -0
- psychopy/sound/microphone.py +357 -0
- psychopy/sound/sound.py +58 -0
- psychopy/sound/transcribe.py +1321 -0
- psychopy/tests/README.md +344 -0
- psychopy/tests/__init__.py +47 -0
- psychopy/tests/data/Electronic_Chime-KevanGC-495939803.wav +0 -0
- psychopy/tests/data/TestCircle_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestCircle_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq10_s0.5.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq10_s0.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq10_s1.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq1_s0.5.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq1_s0.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq1_s1.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq3_s0.5.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq3_s0.png +0 -0
- psychopy/tests/data/TestForm_scrolling_nq3_s1.png +0 -0
- psychopy/tests/data/TestImage_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestImage_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestImage_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestImage_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestImage_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestImage_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestImage_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestImage_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestImage_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestImage_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestImage_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestImage_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestImage_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestImage_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_center center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_left center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_horizontal_right center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_minmax_0.png +0 -0
- psychopy/tests/data/TestProgress_testValue_minmax_1.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_bottom center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_center center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_center center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_top center_0.3.png +0 -0
- psychopy/tests/data/TestProgress_testValue_vertical_top center_0.6.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestProgress_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestROI_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestROI_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestROI_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestROI_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestROI_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestROI_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestROI_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestROI_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestROI_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestROI_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestROI_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestROI_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestROI_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestROI_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestSession_exp1.png +0 -0
- psychopy/tests/data/TestSession_exp2.png +0 -0
- psychopy/tests/data/TestShape_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestShape_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestShape_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestShape_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestShape_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestShape_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestShape_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestShape_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestShape_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestShape_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestShape_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestShape_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestShape_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestShape_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h128_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w128h64_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h128_top_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_center_center.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_top_left.png +0 -0
- psychopy/tests/data/TestTarget_w64h64_top_right.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_0p6.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_0p8.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p2.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p4.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p6.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_1p8.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_2p0.png +0 -0
- psychopy/tests/data/TestTextbox_testLetterSpacing_None.png +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/Test_textbox_testSpeechpoint_-3ovr8_0ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_-3ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_0ovr8_3ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_testSpeechpoint_3ovr8_0ovr8.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h128_top_right.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w128h64_top_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h128_top_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_center_center.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_top_left.png +0 -0
- psychopy/tests/data/Test_textbox_w64h64_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h128_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w128h64_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h128_top_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_bottom_right.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_center_center.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_top_left.png +0 -0
- psychopy/tests/data/Test_uax14_textbox_w64h64_top_right.png +0 -0
- psychopy/tests/data/TextComponent_disabled.psyexp +63 -0
- psychopy/tests/data/TextComponent_not_disabled.psyexp +63 -0
- psychopy/tests/data/aperture1_deg.png +0 -0
- psychopy/tests/data/aperture1_degFlat.png +0 -0
- psychopy/tests/data/aperture1_degFlatPos.png +0 -0
- psychopy/tests/data/aperture1_norm.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground.png +0 -0
- psychopy/tests/data/aperture1_normNoShade.png +0 -0
- psychopy/tests/data/aperture1_pix.png +0 -0
- psychopy/tests/data/aperture1_stencil.png +0 -0
- psychopy/tests/data/aperture2_deg.png +0 -0
- psychopy/tests/data/aperture2_degFlat.png +0 -0
- psychopy/tests/data/aperture2_degFlatPos.png +0 -0
- psychopy/tests/data/aperture2_norm.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground.png +0 -0
- psychopy/tests/data/aperture2_normNoShade.png +0 -0
- psychopy/tests/data/aperture2_pix.png +0 -0
- psychopy/tests/data/aperture2_stencil.png +0 -0
- psychopy/tests/data/beatandrcos_cm.png +0 -0
- psychopy/tests/data/beatandrcos_deg.png +0 -0
- psychopy/tests/data/beatandrcos_degFlat.png +0 -0
- psychopy/tests/data/beatandrcos_degFlatPos.png +0 -0
- psychopy/tests/data/beatandrcos_height.png +0 -0
- psychopy/tests/data/beatandrcos_norm.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground.png +0 -0
- psychopy/tests/data/beatandrcos_pix.png +0 -0
- psychopy/tests/data/beatandrcos_stencil.png +0 -0
- psychopy/tests/data/blend_add_cm.png +0 -0
- psychopy/tests/data/blend_add_deg.png +0 -0
- psychopy/tests/data/blend_add_degFlat.png +0 -0
- psychopy/tests/data/blend_add_degFlatPos.png +0 -0
- psychopy/tests/data/blend_add_height.png +0 -0
- psychopy/tests/data/blend_add_norm.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground.png +0 -0
- psychopy/tests/data/blend_add_normNoShade.png +0 -0
- psychopy/tests/data/blend_add_pix.png +0 -0
- psychopy/tests/data/blend_add_stencil.png +0 -0
- psychopy/tests/data/broken2020_2_5_resources/broken_resources.psyexp +84 -0
- psychopy/tests/data/broken2020_2_5_resources/psychopy72.png +0 -0
- psychopy/tests/data/bufferimg_gabor_cm.png +0 -0
- psychopy/tests/data/bufferimg_gabor_deg.png +0 -0
- psychopy/tests/data/bufferimg_gabor_degFlat.png +0 -0
- psychopy/tests/data/bufferimg_gabor_degFlatPos.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade.png +0 -0
- psychopy/tests/data/bufferimg_gabor_pix.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil.png +0 -0
- psychopy/tests/data/circleHex_cm.png +0 -0
- psychopy/tests/data/circleHex_deg.png +0 -0
- psychopy/tests/data/circleHex_degFlat.png +0 -0
- psychopy/tests/data/circleHex_degFlatPos.png +0 -0
- psychopy/tests/data/circleHex_height.png +0 -0
- psychopy/tests/data/circleHex_norm.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground.png +0 -0
- psychopy/tests/data/circleHex_normNoShade.png +0 -0
- psychopy/tests/data/circleHex_pix.png +0 -0
- psychopy/tests/data/circleHex_stencil.png +0 -0
- psychopy/tests/data/corrFullRandom.csv +16 -0
- psychopy/tests/data/corrFullRandom.tsv +6 -0
- psychopy/tests/data/corrFullRandomTH2.csv +16 -0
- psychopy/tests/data/corrMultiKeyExpWide.csv +3 -0
- psychopy/tests/data/corrMultiKeyTrials.csv +8 -0
- psychopy/tests/data/corrMultiKeyTrials.xlsx +0 -0
- psychopy/tests/data/corrRandom.csv +16 -0
- psychopy/tests/data/corrRandom.tsv +6 -0
- psychopy/tests/data/corrRandomTH2.csv +16 -0
- psychopy/tests/data/corrXlsx.xlsx +0 -0
- psychopy/tests/data/correctScript/js/correctCodeComponent.js +181 -0
- psychopy/tests/data/correctScript/js/correctImageComponent.js +204 -0
- psychopy/tests/data/correctScript/js/correctKeyboardComponent.js +225 -0
- psychopy/tests/data/correctScript/js/correctMouseComponent.js +221 -0
- psychopy/tests/data/correctScript/js/correctMovieComponent.js +210 -0
- psychopy/tests/data/correctScript/js/correctPolygonComponent.js +205 -0
- psychopy/tests/data/correctScript/js/correctSliderComponent.js +209 -0
- psychopy/tests/data/correctScript/js/correctSoundComponent.js +205 -0
- psychopy/tests/data/correctScript/js/correctTextComponent.js +207 -0
- psychopy/tests/data/correctScript/python/correctApertureComponent.py +157 -0
- psychopy/tests/data/correctScript/python/correctCodeComponent.py +135 -0
- psychopy/tests/data/correctScript/python/correctDotsComponent.py +161 -0
- psychopy/tests/data/correctScript/python/correctEnvGratingComponent.py +167 -0
- psychopy/tests/data/correctScript/python/correctFormComponent.py +150 -0
- psychopy/tests/data/correctScript/python/correctGratingComponent.py +158 -0
- psychopy/tests/data/correctScript/python/correctImageComponent.py +160 -0
- psychopy/tests/data/correctScript/python/correctJoyButtonsComponent.py +204 -0
- psychopy/tests/data/correctScript/python/correctJoystickComponent.py +214 -0
- psychopy/tests/data/correctScript/python/correctKeyboardComponent.py +169 -0
- psychopy/tests/data/correctScript/python/correctMicrophoneComponent.py +163 -0
- psychopy/tests/data/correctScript/python/correctMouseComponent.py +174 -0
- psychopy/tests/data/correctScript/python/correctMovieComponent.py +160 -0
- psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +169 -0
- psychopy/tests/data/correctScript/python/correctParallelOutComponent.py +156 -0
- psychopy/tests/data/correctScript/python/correctPatchComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctPolygonComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctQmixPumpComponent.py +174 -0
- psychopy/tests/data/correctScript/python/correctRatingScaleComponent.py +152 -0
- psychopy/tests/data/correctScript/python/correctSliderComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctSoundComponent.py +157 -0
- psychopy/tests/data/correctScript/python/correctStaticComponent.py +176 -0
- psychopy/tests/data/correctScript/python/correctTextComponent.py +159 -0
- psychopy/tests/data/correctScript/python/correctVariableComponent.py +139 -0
- psychopy/tests/data/correctScript/python/correctcedrusButtonBoxComponent.py +199 -0
- psychopy/tests/data/correctScript/python/correctioLabsButtonBoxComponent.py +187 -0
- psychopy/tests/data/dataTest.xlsx +0 -0
- psychopy/tests/data/dots_cm.png +0 -0
- psychopy/tests/data/dots_deg.png +0 -0
- psychopy/tests/data/dots_degFlat.png +0 -0
- psychopy/tests/data/dots_degFlatPos.png +0 -0
- psychopy/tests/data/dots_height.png +0 -0
- psychopy/tests/data/dots_norm.png +0 -0
- psychopy/tests/data/dots_normAddBlend.png +0 -0
- psychopy/tests/data/dots_normHexbackground.png +0 -0
- psychopy/tests/data/dots_normNoShade.png +0 -0
- psychopy/tests/data/dots_pix.png +0 -0
- psychopy/tests/data/dots_stencil.png +0 -0
- psychopy/tests/data/duplicateHeaders.csv +2 -0
- psychopy/tests/data/elarray1_cm.png +0 -0
- psychopy/tests/data/elarray1_deg.png +0 -0
- psychopy/tests/data/elarray1_degFlat.png +0 -0
- psychopy/tests/data/elarray1_degFlatPos.png +0 -0
- psychopy/tests/data/elarray1_height.png +0 -0
- psychopy/tests/data/elarray1_norm.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground.png +0 -0
- psychopy/tests/data/elarray1_pix.png +0 -0
- psychopy/tests/data/elarray1_stencil.png +0 -0
- psychopy/tests/data/envelopeandrcos_cm.png +0 -0
- psychopy/tests/data/envelopeandrcos_deg.png +0 -0
- psychopy/tests/data/envelopeandrcos_degFlat.png +0 -0
- psychopy/tests/data/envelopeandrcos_degFlatPos.png +0 -0
- psychopy/tests/data/envelopeandrcos_height.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground.png +0 -0
- psychopy/tests/data/envelopeandrcos_pix.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_cm.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_deg.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_degFlat.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_degFlatPos.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_pix.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil.png +0 -0
- psychopy/tests/data/filltext.png +0 -0
- psychopy/tests/data/form_font_demographics.png +0 -0
- psychopy/tests/data/form_font_demographics.xlsx +0 -0
- psychopy/tests/data/form_font_languages.png +0 -0
- psychopy/tests/data/form_font_languages.xlsx +0 -0
- psychopy/tests/data/form_font_nonstandard.png +0 -0
- psychopy/tests/data/futureParams.psyexp +150 -0
- psychopy/tests/data/gabor1_cm.png +0 -0
- psychopy/tests/data/gabor1_deg.png +0 -0
- psychopy/tests/data/gabor1_degFlat.png +0 -0
- psychopy/tests/data/gabor1_degFlatPos.png +0 -0
- psychopy/tests/data/gabor1_height.png +0 -0
- psychopy/tests/data/gabor1_norm.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground.png +0 -0
- psychopy/tests/data/gabor1_normNoShade.png +0 -0
- psychopy/tests/data/gabor1_pix.png +0 -0
- psychopy/tests/data/gabor1_stencil.png +0 -0
- psychopy/tests/data/gabor2_cm.png +0 -0
- psychopy/tests/data/gabor2_deg.png +0 -0
- psychopy/tests/data/gabor2_degFlat.png +0 -0
- psychopy/tests/data/gabor2_degFlatPos.png +0 -0
- psychopy/tests/data/gabor2_height.png +0 -0
- psychopy/tests/data/gabor2_norm.png +0 -0
- psychopy/tests/data/gabor2_normAddBlend.png +0 -0
- psychopy/tests/data/gabor2_normHexbackground.png +0 -0
- psychopy/tests/data/gabor2_normNoShade.png +0 -0
- psychopy/tests/data/gabor2_pix.png +0 -0
- psychopy/tests/data/gabor2_stencil.png +0 -0
- psychopy/tests/data/ghost_stroop.psyexp +131 -0
- psychopy/tests/data/ghost_trialTypes.xlsx +0 -0
- psychopy/tests/data/green_48000.flac.dist +0 -0
- psychopy/tests/data/greyscale.jpg +0 -0
- psychopy/tests/data/greyscale2.png +0 -0
- psychopy/tests/data/greyscale2_cm.png +0 -0
- psychopy/tests/data/greyscale2_deg.png +0 -0
- psychopy/tests/data/greyscale2_degFlat.png +0 -0
- psychopy/tests/data/greyscale2_degFlatPos.png +0 -0
- psychopy/tests/data/greyscale2_height.png +0 -0
- psychopy/tests/data/greyscale2_norm.png +0 -0
- psychopy/tests/data/greyscale2_normAddBlend.png +0 -0
- psychopy/tests/data/greyscale2_normHexbackground.png +0 -0
- psychopy/tests/data/greyscale2_normNoShade.png +0 -0
- psychopy/tests/data/greyscale2_pix.png +0 -0
- psychopy/tests/data/greyscale2_stencil.png +0 -0
- psychopy/tests/data/greyscaleLowContr_cm.png +0 -0
- psychopy/tests/data/greyscaleLowContr_deg.png +0 -0
- psychopy/tests/data/greyscaleLowContr_degFlat.png +0 -0
- psychopy/tests/data/greyscaleLowContr_degFlatPos.png +0 -0
- psychopy/tests/data/greyscaleLowContr_height.png +0 -0
- psychopy/tests/data/greyscaleLowContr_norm.png +0 -0
- psychopy/tests/data/greyscaleLowContr_normAddBlend.png +0 -0
- psychopy/tests/data/greyscaleLowContr_normHexbackground.png +0 -0
- psychopy/tests/data/greyscaleLowContr_normNoShade.png +0 -0
- psychopy/tests/data/greyscaleLowContr_pix.png +0 -0
- psychopy/tests/data/greyscaleLowContr_stencil.png +0 -0
- psychopy/tests/data/greyscale_cm.png +0 -0
- psychopy/tests/data/greyscale_deg.png +0 -0
- psychopy/tests/data/greyscale_degFlat.png +0 -0
- psychopy/tests/data/greyscale_degFlatPos.png +0 -0
- psychopy/tests/data/greyscale_height.png +0 -0
- psychopy/tests/data/greyscale_norm.png +0 -0
- psychopy/tests/data/greyscale_normAddBlend.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground.png +0 -0
- psychopy/tests/data/greyscale_normNoShade.png +0 -0
- psychopy/tests/data/greyscale_pix.png +0 -0
- psychopy/tests/data/greyscale_stencil.png +0 -0
- psychopy/tests/data/imageAndGauss_cm.png +0 -0
- psychopy/tests/data/imageAndGauss_deg.png +0 -0
- psychopy/tests/data/imageAndGauss_degFlat.png +0 -0
- psychopy/tests/data/imageAndGauss_degFlatPos.png +0 -0
- psychopy/tests/data/imageAndGauss_height.png +0 -0
- psychopy/tests/data/imageAndGauss_norm.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade.png +0 -0
- psychopy/tests/data/imageAndGauss_pix.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil.png +0 -0
- psychopy/tests/data/movFrame1_cm.png +0 -0
- psychopy/tests/data/movFrame1_deg.png +0 -0
- psychopy/tests/data/movFrame1_degFlat.png +0 -0
- psychopy/tests/data/movFrame1_degFlatPos.png +0 -0
- psychopy/tests/data/movFrame1_height.png +0 -0
- psychopy/tests/data/movFrame1_norm.png +0 -0
- psychopy/tests/data/movFrame1_normAddBlend.png +0 -0
- psychopy/tests/data/movFrame1_normHexbackground.png +0 -0
- psychopy/tests/data/movFrame1_normNoShade.png +0 -0
- psychopy/tests/data/movFrame1_pix.png +0 -0
- psychopy/tests/data/movFrame1_stencil.png +0 -0
- psychopy/tests/data/multiKeypressExperiment.psydat +357 -0
- psychopy/tests/data/multiKeypressTrialhandler.psydat +252 -0
- psychopy/tests/data/multiStairConds.xlsx +0 -0
- psychopy/tests/data/multiStairQuestPlus.xlsx +0 -0
- psychopy/tests/data/newstyle.psydat +6155 -0
- psychopy/tests/data/noiseAndRcos_cm.png +0 -0
- psychopy/tests/data/noiseAndRcos_deg.png +0 -0
- psychopy/tests/data/noiseAndRcos_degFlat.png +0 -0
- psychopy/tests/data/noiseAndRcos_degFlatPos.png +0 -0
- psychopy/tests/data/noiseAndRcos_height.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade.png +0 -0
- psychopy/tests/data/noiseAndRcos_pix.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_cm.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_deg.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_degFlat.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_degFlatPos.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_pix.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil.png +0 -0
- psychopy/tests/data/numpyImage_cm.png +0 -0
- psychopy/tests/data/numpyImage_deg.png +0 -0
- psychopy/tests/data/numpyImage_degFlat.png +0 -0
- psychopy/tests/data/numpyImage_degFlatPos.png +0 -0
- psychopy/tests/data/numpyImage_height.png +0 -0
- psychopy/tests/data/numpyImage_norm.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade.png +0 -0
- psychopy/tests/data/numpyImage_pix.png +0 -0
- psychopy/tests/data/numpyImage_stencil.png +0 -0
- psychopy/tests/data/numpyLowContr_cm.png +0 -0
- psychopy/tests/data/numpyLowContr_deg.png +0 -0
- psychopy/tests/data/numpyLowContr_degFlat.png +0 -0
- psychopy/tests/data/numpyLowContr_degFlatPos.png +0 -0
- psychopy/tests/data/numpyLowContr_height.png +0 -0
- psychopy/tests/data/numpyLowContr_norm.png +0 -0
- psychopy/tests/data/numpyLowContr_normAddBlend.png +0 -0
- psychopy/tests/data/numpyLowContr_normHexbackground.png +0 -0
- psychopy/tests/data/numpyLowContr_normNoShade.png +0 -0
- psychopy/tests/data/numpyLowContr_pix.png +0 -0
- psychopy/tests/data/numpyLowContr_stencil.png +0 -0
- psychopy/tests/data/oldstyle.psydat +1534 -0
- psychopy/tests/data/oldstyle_stair.psydat +263 -0
- psychopy/tests/data/ratingscale1_cm.png +0 -0
- psychopy/tests/data/ratingscale1_deg.png +0 -0
- psychopy/tests/data/ratingscale1_degFlat.png +0 -0
- psychopy/tests/data/ratingscale1_degFlatPos.png +0 -0
- psychopy/tests/data/ratingscale1_height.png +0 -0
- psychopy/tests/data/ratingscale1_norm.png +0 -0
- psychopy/tests/data/ratingscale1_normAddBlend.png +0 -0
- psychopy/tests/data/ratingscale1_normHexbackground.png +0 -0
- psychopy/tests/data/ratingscale1_normNoShade.png +0 -0
- psychopy/tests/data/ratingscale1_pix.png +0 -0
- psychopy/tests/data/ratingscale1_stencil.png +0 -0
- psychopy/tests/data/red_16000.flac.dist +0 -0
- psychopy/tests/data/retroListParam.psyexp +82 -0
- psychopy/tests/data/right_to_left_unidcode.xlsx +0 -0
- psychopy/tests/data/sample.meshwarp.data +11522 -0
- psychopy/tests/data/shape2_1_cm.png +0 -0
- psychopy/tests/data/shape2_1_deg.png +0 -0
- psychopy/tests/data/shape2_1_degFlat.png +0 -0
- psychopy/tests/data/shape2_1_degFlatPos.png +0 -0
- psychopy/tests/data/shape2_1_height.png +0 -0
- psychopy/tests/data/shape2_1_norm.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade.png +0 -0
- psychopy/tests/data/shape2_1_pix.png +0 -0
- psychopy/tests/data/shape2_1_stencil.png +0 -0
- psychopy/tests/data/shape2_2_cm.png +0 -0
- psychopy/tests/data/shape2_2_deg.png +0 -0
- psychopy/tests/data/shape2_2_degFlat.png +0 -0
- psychopy/tests/data/shape2_2_degFlatPos.png +0 -0
- psychopy/tests/data/shape2_2_height.png +0 -0
- psychopy/tests/data/shape2_2_norm.png +0 -0
- psychopy/tests/data/shape2_2_normAddBlend.png +0 -0
- psychopy/tests/data/shape2_2_normHexbackground.png +0 -0
- psychopy/tests/data/shape2_2_normNoShade.png +0 -0
- psychopy/tests/data/shape2_2_pix.png +0 -0
- psychopy/tests/data/shape2_2_stencil.png +0 -0
- psychopy/tests/data/simpleimage1_cm.png +0 -0
- psychopy/tests/data/simpleimage1_deg.png +0 -0
- psychopy/tests/data/simpleimage1_degFlat.png +0 -0
- psychopy/tests/data/simpleimage1_degFlatPos.png +0 -0
- psychopy/tests/data/simpleimage1_height.png +0 -0
- psychopy/tests/data/simpleimage1_norm.png +0 -0
- psychopy/tests/data/simpleimage1_normAddBlend.png +0 -0
- psychopy/tests/data/simpleimage1_normHexbackground.png +0 -0
- psychopy/tests/data/simpleimage1_normNoShade.png +0 -0
- psychopy/tests/data/simpleimage1_pix.png +0 -0
- psychopy/tests/data/simpleimage1_stencil.png +0 -0
- psychopy/tests/data/test001EntryImporting.psyexp +66 -0
- psychopy/tests/data/testMovie.mp4 +0 -0
- psychopy/tests/data/test_basic_run.py +1 -0
- psychopy/tests/data/test_circle_radius_.1height.png +0 -0
- psychopy/tests/data/test_circle_radius_.2height.png +0 -0
- psychopy/tests/data/test_circle_radius_10pix.png +0 -0
- psychopy/tests/data/test_circle_radius_20pix.png +0 -0
- psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
- psychopy/tests/data/test_form_combinations_choice_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_choice_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_choice_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_choice_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_description_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_free text_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_heading_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_radio_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_rating_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigItem.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigItemOverflow.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigResp.png +0 -0
- psychopy/tests/data/test_form_combinations_slider_bigRespOverflow.png +0 -0
- psychopy/tests/data/test_get_resources/blue.png +0 -0
- psychopy/tests/data/test_get_resources/groupA.csv +3 -0
- psychopy/tests/data/test_get_resources/groupB.csv +3 -0
- psychopy/tests/data/test_get_resources/groups.csv +3 -0
- psychopy/tests/data/test_get_resources/handledbyrm_constrloop.psyexp +143 -0
- psychopy/tests/data/test_get_resources/handledbyrm_noloop.psyexp +114 -0
- psychopy/tests/data/test_get_resources/handledbyrm_recurloop.psyexp +138 -0
- psychopy/tests/data/test_get_resources/handledbyrm_strloop.psyexp +126 -0
- psychopy/tests/data/test_get_resources/handledbystatic_constrloop.psyexp +141 -0
- psychopy/tests/data/test_get_resources/handledbystatic_noloop.psyexp +112 -0
- psychopy/tests/data/test_get_resources/handledbystatic_recurloop.psyexp +136 -0
- psychopy/tests/data/test_get_resources/handledbystatic_strloop.psyexp +124 -0
- psychopy/tests/data/test_get_resources/unhandled_constrloop.psyexp +128 -0
- psychopy/tests/data/test_get_resources/unhandled_noloop.psyexp +99 -0
- psychopy/tests/data/test_get_resources/unhandled_recurloop.psyexp +123 -0
- psychopy/tests/data/test_get_resources/unhandled_strloop.psyexp +111 -0
- psychopy/tests/data/test_get_resources/white.png +0 -0
- psychopy/tests/data/test_get_resources/yellow.png +0 -0
- psychopy/tests/data/test_image_aspect_default_None.png +0 -0
- psychopy/tests/data/test_image_aspect_default_xFull_yNone.png +0 -0
- psychopy/tests/data/test_image_aspect_default_xNone_yFull.png +0 -0
- psychopy/tests/data/test_image_aspect_default_xNone_yNone.png +0 -0
- psychopy/tests/data/test_image_flip_anchor_horiz.png +0 -0
- psychopy/tests/data/test_image_flip_anchor_vert.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/test_loops/testLoopsBlocks.psyexp +161 -0
- psychopy/tests/data/test_loops/testStaircase.psyexp +105 -0
- psychopy/tests/data/test_loops/test_current_loop_attr.psyexp +185 -0
- psychopy/tests/data/test_panorama/panoramaTestImage.png +0 -0
- psychopy/tests/data/test_panorama/panoramaTestImage.svg +1 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_-0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-0.3_0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_-0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_-1.0_0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_-1.0.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.0_1.0.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_-0.3.png +0 -0
- psychopy/tests/data/test_panorama/testPanorama_mvmt_0.3_0.3.png +0 -0
- psychopy/tests/data/test_resources.psyexp +491 -0
- psychopy/tests/data/test_session/outside_root/externalExp.psyexp +116 -0
- psychopy/tests/data/test_session/root/annotation/annotation.psyexp +161 -0
- psychopy/tests/data/test_session/root/error/error.psyexp +93 -0
- psychopy/tests/data/test_session/root/exp1/exp1.psyexp +133 -0
- psychopy/tests/data/test_session/root/exp2/exp2.psyexp +133 -0
- psychopy/tests/data/test_session/root/frameRate/frameRate.psyexp +114 -0
- psychopy/tests/data/test_session/root/invUseVersion/invUseVersion.psyexp +133 -0
- psychopy/tests/data/test_session/root/testClockFormat/testClockFormat.psyexp +122 -0
- psychopy/tests/data/test_session/root/testCtrls/testCtrls.psyexp +115 -0
- psychopy/tests/data/test_session/root/testEditExpInfo/testEditExpInfo.psyexp +135 -0
- psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
- psychopy/tests/data/test_session/root/testNamedButtonBox/testNamedButtonBox.psyexp +145 -0
- psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
- psychopy/tests/data/test_slider_horiz_accute_horiz.png +0 -0
- psychopy/tests/data/test_slider_horiz_accute_vert.png +0 -0
- psychopy/tests/data/test_slider_horiz_horiz.png +0 -0
- psychopy/tests/data/test_slider_horiz_obtuse_horiz.png +0 -0
- psychopy/tests/data/test_slider_horiz_obtuse_vert.png +0 -0
- psychopy/tests/data/test_slider_horiz_vert.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_blanks.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_clustered.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_morelabels.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_morelabelsclustered.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_moreticks.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_moreticksclustered.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_nolabels.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_noticks.png +0 -0
- psychopy/tests/data/test_slider_ticklabelloc_simple.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_False_flip_False.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_False_flip_True.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_True_flip_False.png +0 -0
- psychopy/tests/data/test_slider_triangle_horiz_True_flip_True.png +0 -0
- psychopy/tests/data/test_sounds/default_16000.wav +0 -0
- psychopy/tests/data/test_sounds/default_192000.wav +0 -0
- psychopy/tests/data/test_sounds/default_22050.wav +0 -0
- psychopy/tests/data/test_sounds/default_32000.wav +0 -0
- psychopy/tests/data/test_sounds/default_44100.wav +0 -0
- psychopy/tests/data/test_sounds/default_48000.wav +0 -0
- psychopy/tests/data/test_sounds/default_8000.wav +0 -0
- psychopy/tests/data/test_sounds/default_96000.wav +0 -0
- psychopy/tests/data/test_static_component_script.psyexp +76 -0
- psychopy/tests/data/test_win_bg_large_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_large_500_default.png +0 -0
- psychopy/tests/data/test_win_bg_small_200_default.png +0 -0
- psychopy/tests/data/test_win_bg_small_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_200_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_500_default.png +0 -0
- psychopy/tests/data/test_win_bg_tall_fill_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_200_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_256_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_500_default.png +0 -0
- psychopy/tests/data/test_win_bg_wide_fill_default.png +0 -0
- psychopy/tests/data/test_win_bgcolor_blue.png +0 -0
- psychopy/tests/data/test_win_bgcolor_green.png +0 -0
- psychopy/tests/data/test_win_bgcolor_red.png +0 -0
- psychopy/tests/data/testimage.jpg +0 -0
- psychopy/tests/data/testimagegray.jpg +0 -0
- psychopy/tests/data/testpixels.png +0 -0
- psychopy/tests/data/testwedges.png +0 -0
- psychopy/tests/data/text1_cm.png +0 -0
- psychopy/tests/data/text1_deg.png +0 -0
- psychopy/tests/data/text1_degFlat.png +0 -0
- psychopy/tests/data/text1_degFlatPos.png +0 -0
- psychopy/tests/data/text1_height.png +0 -0
- psychopy/tests/data/text1_norm.png +0 -0
- psychopy/tests/data/text1_normAddBlend.png +0 -0
- psychopy/tests/data/text1_normHexbackground.png +0 -0
- psychopy/tests/data/text1_normNoShade.png +0 -0
- psychopy/tests/data/text1_pix.png +0 -0
- psychopy/tests/data/text1_stencil.png +0 -0
- psychopy/tests/data/text2_cm.png +0 -0
- psychopy/tests/data/text2_deg.png +0 -0
- psychopy/tests/data/text2_degFlat.png +0 -0
- psychopy/tests/data/text2_degFlatPos.png +0 -0
- psychopy/tests/data/text2_norm.png +0 -0
- psychopy/tests/data/text2_normNoShade.png +0 -0
- psychopy/tests/data/text2_pix.png +0 -0
- psychopy/tests/data/textbox_charcolors_default_roygbiv.png +0 -0
- psychopy/tests/data/textbox_charcolors_default_white_hello_black_there.png +0 -0
- psychopy/tests/data/textbox_default_align_bottom_center.png +0 -0
- psychopy/tests/data/textbox_default_align_bottom_left.png +0 -0
- psychopy/tests/data/textbox_default_align_bottom_right.png +0 -0
- psychopy/tests/data/textbox_default_align_center.png +0 -0
- psychopy/tests/data/textbox_default_align_center_center.png +0 -0
- psychopy/tests/data/textbox_default_align_center_left.png +0 -0
- psychopy/tests/data/textbox_default_align_center_right.png +0 -0
- psychopy/tests/data/textbox_default_align_centre.png +0 -0
- psychopy/tests/data/textbox_default_align_centre_centre.png +0 -0
- psychopy/tests/data/textbox_default_align_more_than_two_words.png +0 -0
- psychopy/tests/data/textbox_default_align_someword.png +0 -0
- psychopy/tests/data/textbox_default_align_top_center.png +0 -0
- psychopy/tests/data/textbox_default_align_top_left.png +0 -0
- psychopy/tests/data/textbox_default_align_top_right.png +0 -0
- psychopy/tests/data/textbox_default_colors_WOB.png +0 -0
- psychopy/tests/data/textbox_default_colors_exemplar1.png +0 -0
- psychopy/tests/data/textbox_default_colors_exemplar2.png +0 -0
- psychopy/tests/data/textbox_default_colors_exemplar3.png +0 -0
- psychopy/tests/data/textbox_default_colors_tyke1.png +0 -0
- psychopy/tests/data/textbox_default_colors_tyke2.png +0 -0
- psychopy/tests/data/textbox_default_colors_tyke3.png +0 -0
- psychopy/tests/data/textbox_default_cutoff_top.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_1.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_2.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_3.png +0 -0
- psychopy/tests/data/textbox_default_exemplar_4.png +0 -0
- psychopy/tests/data/textbox_default_tyke_1.png +0 -0
- psychopy/tests/data/textbox_default_tyke_2.png +0 -0
- psychopy/tests/data/textbox_typing_blank.png +0 -0
- psychopy/tests/data/textbox_typing_longKoeran.png +0 -0
- psychopy/tests/data/textbox_typing_longWord.png +0 -0
- psychopy/tests/data/textbox_typing_navDel.png +0 -0
- psychopy/tests/data/textbox_typing_navLR.png +0 -0
- psychopy/tests/data/textbox_typing_newline.png +0 -0
- psychopy/tests/data/textbox_typing_pangram.png +0 -0
- psychopy/tests/data/textbox_uax14_align_bottom_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_bottom_left.png +0 -0
- psychopy/tests/data/textbox_uax14_align_bottom_right.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center_left.png +0 -0
- psychopy/tests/data/textbox_uax14_align_center_right.png +0 -0
- psychopy/tests/data/textbox_uax14_align_centre.png +0 -0
- psychopy/tests/data/textbox_uax14_align_centre_centre.png +0 -0
- psychopy/tests/data/textbox_uax14_align_more_than_two_words.png +0 -0
- psychopy/tests/data/textbox_uax14_align_someword.png +0 -0
- psychopy/tests/data/textbox_uax14_align_top_center.png +0 -0
- psychopy/tests/data/textbox_uax14_align_top_left.png +0 -0
- psychopy/tests/data/textbox_uax14_align_top_right.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_WOB.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_exemplar1.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_exemplar2.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_exemplar3.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_tyke1.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_tyke2.png +0 -0
- psychopy/tests/data/textbox_uax14_colors_tyke3.png +0 -0
- psychopy/tests/data/textbox_uax14_cutoff_top.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_1.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_2.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_3.png +0 -0
- psychopy/tests/data/textbox_uax14_exemplar_4.png +0 -0
- psychopy/tests/data/textbox_uax14_tyke_1.png +0 -0
- psychopy/tests/data/textbox_uax14_tyke_2.png +0 -0
- psychopy/tests/data/trialTypes.csv +1 -0
- psychopy/tests/data/trialTypes.docx +0 -0
- psychopy/tests/data/trialTypes.pkl +0 -0
- psychopy/tests/data/trialTypes.tsv +7 -0
- psychopy/tests/data/trialTypes.xls +0 -0
- psychopy/tests/data/trialTypes.xlsx +0 -0
- psychopy/tests/data/trialTypes_eu.csv +7 -0
- psychopy/tests/data/trialsBlankCols.xlsx +0 -0
- psychopy/tests/data/wedge1_cm.png +0 -0
- psychopy/tests/data/wedge1_deg.png +0 -0
- psychopy/tests/data/wedge1_degFlat.png +0 -0
- psychopy/tests/data/wedge1_degFlatPos.png +0 -0
- psychopy/tests/data/wedge1_height.png +0 -0
- psychopy/tests/data/wedge1_norm.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground.png +0 -0
- psychopy/tests/data/wedge1_normNoShade.png +0 -0
- psychopy/tests/data/wedge1_pix.png +0 -0
- psychopy/tests/data/wedge1_stencil.png +0 -0
- psychopy/tests/data/wedge2_cm.png +0 -0
- psychopy/tests/data/wedge2_deg.png +0 -0
- psychopy/tests/data/wedge2_degFlat.png +0 -0
- psychopy/tests/data/wedge2_degFlatPos.png +0 -0
- psychopy/tests/data/wedge2_height.png +0 -0
- psychopy/tests/data/wedge2_norm.png +0 -0
- psychopy/tests/data/wedge2_normAddBlend.png +0 -0
- psychopy/tests/data/wedge2_normHexbackground.png +0 -0
- psychopy/tests/data/wedge2_normNoShade.png +0 -0
- psychopy/tests/data/wedge2_pix.png +0 -0
- psychopy/tests/data/wedge2_stencil.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale-2_2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_-1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_1_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_-2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_2_pos-0.4_0.png +0 -0
- psychopy/tests/data/winScalePos_ori0_scale2_2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale-2_2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale1_-1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale1_1_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale2_-2_pos0_0.png +0 -0
- psychopy/tests/data/winScalePos_ori45_scale2_2_pos0_0.png +0 -0
- psychopy/tests/doc/run_btn.png +0 -0
- psychopy/tests/doc/test-suite-bugs.jpg +0 -0
- psychopy/tests/doc/user-bugs.jpg +0 -0
- psychopy/tests/dummy_xorg.conf +21 -0
- psychopy/tests/run.py +50 -0
- psychopy/tests/test_Installation.py +38 -0
- psychopy/tests/test_alerts/test_alerts.py +37 -0
- psychopy/tests/test_alerts/test_alerttools.py +132 -0
- psychopy/tests/test_app/__init__.py +0 -0
- psychopy/tests/test_app/conftest.py +40 -0
- psychopy/tests/test_app/test_builder/__init__.py +0 -0
- psychopy/tests/test_app/test_builder/test_BuilderFrame.py +166 -0
- psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +133 -0
- psychopy/tests/test_app/test_builder/test_ComponentDialogs.py +98 -0
- psychopy/tests/test_app/test_command_line.py +65 -0
- psychopy/tests/test_app/test_runner/__init__.py +0 -0
- psychopy/tests/test_app/test_runner/test_RunnerFrame.py +166 -0
- psychopy/tests/test_app/test_speed.py +147 -0
- psychopy/tests/test_app/test_themes/test_icons.py +79 -0
- psychopy/tests/test_codecov.py +29 -0
- psychopy/tests/test_colors/test_Color.py +41 -0
- psychopy/tests/test_data/dataPrev.xlsx +0 -0
- psychopy/tests/test_data/test_ExperimentHandler.py +171 -0
- psychopy/tests/test_data/test_MultiStairHandler.py +174 -0
- psychopy/tests/test_data/test_StairHandlers.py +1241 -0
- psychopy/tests/test_data/test_TrialHandler.py +335 -0
- psychopy/tests/test_data/test_TrialHandler2.py +584 -0
- psychopy/tests/test_data/test_TrialHandlerExt.py +359 -0
- psychopy/tests/test_data/test_fitFunctions.py +101 -0
- psychopy/tests/test_data/test_utils.py +173 -0
- psychopy/tests/test_data/test_xlsx.py +92 -0
- psychopy/tests/test_demos/test_builder_demos.py +52 -0
- psychopy/tests/test_experiment/__init__.py +0 -0
- psychopy/tests/test_experiment/known_py_diffs.txt +47 -0
- psychopy/tests/test_experiment/needs_wx/__init__.py +0 -0
- psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +14780 -0
- psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +130 -0
- psychopy/tests/test_experiment/needs_wx/test_Experiment.py +406 -0
- psychopy/tests/test_experiment/needs_wx/test_components.py +170 -0
- psychopy/tests/test_experiment/test_component_compile_js.py +59 -0
- psychopy/tests/test_experiment/test_component_compile_python.py +165 -0
- psychopy/tests/test_experiment/test_components/__init__.py +1 -0
- psychopy/tests/test_experiment/test_components/test_ButtonBoxComponent.py +218 -0
- psychopy/tests/test_experiment/test_components/test_CodeComponent.py +70 -0
- psychopy/tests/test_experiment/test_components/test_GratingComponent.py +7 -0
- psychopy/tests/test_experiment/test_components/test_ImageComponent.py +8 -0
- psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
- psychopy/tests/test_experiment/test_components/test_MouseComponent.py +136 -0
- psychopy/tests/test_experiment/test_components/test_PolygonComponent.py +65 -0
- psychopy/tests/test_experiment/test_components/test_ResourceManagerComponent.py +50 -0
- psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
- psychopy/tests/test_experiment/test_components/test_SettingsComponent.py +80 -0
- psychopy/tests/test_experiment/test_components/test_StaticComponent.py +51 -0
- psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
- psychopy/tests/test_experiment/test_components/test_all_components.py +104 -0
- psychopy/tests/test_experiment/test_components/test_base_components.py +477 -0
- psychopy/tests/test_experiment/test_experiment.py +199 -0
- psychopy/tests/test_experiment/test_loops.py +103 -0
- psychopy/tests/test_experiment/test_params.py +363 -0
- psychopy/tests/test_experiment/test_py2js.py +230 -0
- psychopy/tests/test_experiment/test_routines/__init__.py +1 -0
- psychopy/tests/test_experiment/test_routines/test_EyetrackerCalibrationRoutine.py +9 -0
- psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +9 -0
- psychopy/tests/test_experiment/test_routines/test_all_routines.py +23 -0
- psychopy/tests/test_experiment/test_routines/test_base_routine.py +154 -0
- psychopy/tests/test_experiment/test_routines/test_standalone_routines.py +36 -0
- psychopy/tests/test_gui/test_DlgFromDictQt.py +82 -0
- psychopy/tests/test_gui/test_DlgFromDictWx.py +82 -0
- psychopy/tests/test_hardware/__init__.py +0 -0
- psychopy/tests/test_hardware/test_device_manager.py +36 -0
- psychopy/tests/test_hardware/test_emulator.py +106 -0
- psychopy/tests/test_hardware/test_gammasci.py +35 -0
- psychopy/tests/test_hardware/test_keyboard.py +241 -0
- psychopy/tests/test_hardware/test_keyboard_events.py +362 -0
- psychopy/tests/test_hardware/test_photodiode.py +66 -0
- psychopy/tests/test_hardware/test_ports.py +129 -0
- psychopy/tests/test_iohub/__init__.py +1 -0
- psychopy/tests/test_iohub/test_computer.py +124 -0
- psychopy/tests/test_iohub/test_event_get_and_clear.py +94 -0
- psychopy/tests/test_iohub/test_keyboard.py +91 -0
- psychopy/tests/test_iohub/test_launch.py +19 -0
- psychopy/tests/test_iohub/testutil.py +54 -0
- psychopy/tests/test_liaison/test_Liaison.py +275 -0
- psychopy/tests/test_misc/__init__.py +0 -0
- psychopy/tests/test_misc/memory_usage.py +164 -0
- psychopy/tests/test_misc/test_GammaFun.py +15 -0
- psychopy/tests/test_misc/test_clock.py +63 -0
- psychopy/tests/test_misc/test_color.py +205 -0
- psychopy/tests/test_misc/test_core.py +451 -0
- psychopy/tests/test_misc/test_event.py +308 -0
- psychopy/tests/test_misc/test_info.py +18 -0
- psychopy/tests/test_misc/test_layout.py +49 -0
- psychopy/tests/test_misc/test_locale.py +38 -0
- psychopy/tests/test_misc/test_web.py +22 -0
- psychopy/tests/test_monitors/test_monitors.py +91 -0
- psychopy/tests/test_plugins/__init__.py +0 -0
- psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
- psychopy/tests/test_preferences/__init__.py +0 -0
- psychopy/tests/test_preferences/test_prefs.py +28 -0
- psychopy/tests/test_session/test_Session.py +257 -0
- psychopy/tests/test_sound/__init__.py +0 -0
- psychopy/tests/test_sound/test_audioclip.py +331 -0
- psychopy/tests/test_sound/test_hamming.py +45 -0
- psychopy/tests/test_sound/test_sound.py +138 -0
- psychopy/tests/test_sound/test_sound_pygame.py +67 -0
- psychopy/tests/test_tools/test_animationtools.py +51 -0
- psychopy/tests/test_tools/test_arraytools.py +242 -0
- psychopy/tests/test_tools/test_attributetools.py +257 -0
- psychopy/tests/test_tools/test_colorspacetools.py +150 -0
- psychopy/tests/test_tools/test_environmenttools.py +52 -0
- psychopy/tests/test_tools/test_fileerrortools.py +97 -0
- psychopy/tests/test_tools/test_filetools.py +104 -0
- psychopy/tests/test_tools/test_imagetools.py +57 -0
- psychopy/tests/test_tools/test_mathtools.py +688 -0
- psychopy/tests/test_tools/test_stringtools.py +143 -0
- psychopy/tests/test_tools/test_versionchooser.py +209 -0
- psychopy/tests/test_tools/test_viewtools.py +168 -0
- psychopy/tests/test_validators/__init__.py +0 -0
- psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
- psychopy/tests/test_visual/__init__.py +0 -0
- psychopy/tests/test_visual/measure_parity.py +243 -0
- psychopy/tests/test_visual/test_all_stimuli.py +655 -0
- psychopy/tests/test_visual/test_basevisual.py +564 -0
- psychopy/tests/test_visual/test_brush.py +68 -0
- psychopy/tests/test_visual/test_button.py +15 -0
- psychopy/tests/test_visual/test_circle.py +74 -0
- psychopy/tests/test_visual/test_contains_overlaps.py +242 -0
- psychopy/tests/test_visual/test_custommouse.py +47 -0
- psychopy/tests/test_visual/test_dots.py +155 -0
- psychopy/tests/test_visual/test_form.py +414 -0
- psychopy/tests/test_visual/test_framepacking.py +41 -0
- psychopy/tests/test_visual/test_gamma.py +152 -0
- psychopy/tests/test_visual/test_glfw_backend.py +14 -0
- psychopy/tests/test_visual/test_image.py +219 -0
- psychopy/tests/test_visual/test_panorama.py +41 -0
- psychopy/tests/test_visual/test_progress.py +96 -0
- psychopy/tests/test_visual/test_projections.py +215 -0
- psychopy/tests/test_visual/test_projections_interactive.py +163 -0
- psychopy/tests/test_visual/test_roi.py +105 -0
- psychopy/tests/test_visual/test_shape.py +23 -0
- psychopy/tests/test_visual/test_slider.py +328 -0
- psychopy/tests/test_visual/test_target.py +35 -0
- psychopy/tests/test_visual/test_textbox.py +508 -0
- psychopy/tests/test_visual/test_winFlipTiming.py +95 -0
- psychopy/tests/test_visual/test_winScalePos.py +78 -0
- psychopy/tests/test_visual/test_window.py +124 -0
- psychopy/tests/utils.py +372 -0
- psychopy/tools/LineBreak.txt +3597 -0
- psychopy/tools/__init__.py +9 -0
- psychopy/tools/animationtools.py +49 -0
- psychopy/tools/apptools.py +32 -0
- psychopy/tools/arraytools.py +561 -0
- psychopy/tools/attributetools.py +263 -0
- psychopy/tools/audiotools.py +361 -0
- psychopy/tools/colorspacetools.py +717 -0
- psychopy/tools/coordinatetools.py +104 -0
- psychopy/tools/environmenttools.py +62 -0
- psychopy/tools/fileerrortools.py +66 -0
- psychopy/tools/filetools.py +406 -0
- psychopy/tools/fontmanager.py +1065 -0
- psychopy/tools/gltools.py +7367 -0
- psychopy/tools/imagetools.py +65 -0
- psychopy/tools/linebreak.py +322 -0
- psychopy/tools/mathtools.py +4910 -0
- psychopy/tools/monitorunittools.py +276 -0
- psychopy/tools/movietools.py +1111 -0
- psychopy/tools/pkgtools.py +654 -0
- psychopy/tools/plottools.py +25 -0
- psychopy/tools/rifttools.py +76 -0
- psychopy/tools/stereotools.py +9 -0
- psychopy/tools/stimulustools.py +198 -0
- psychopy/tools/stringtools.py +466 -0
- psychopy/tools/systemtools.py +1331 -0
- psychopy/tools/typetools.py +52 -0
- psychopy/tools/unittools.py +16 -0
- psychopy/tools/versionchooser.py +604 -0
- psychopy/tools/viewtools.py +1068 -0
- psychopy/tools/wizard.py +804 -0
- psychopy/validation/__init__.py +6 -0
- psychopy/validation/audio.py +78 -0
- psychopy/validation/visual.py +119 -0
- psychopy/visual/__init__.py +121 -0
- psychopy/visual/aperture.py +333 -0
- psychopy/visual/backends/__init__.py +77 -0
- psychopy/visual/backends/_base.py +481 -0
- psychopy/visual/backends/gamma.py +349 -0
- psychopy/visual/backends/glfwbackend.py +24 -0
- psychopy/visual/backends/pygamebackend.py +343 -0
- psychopy/visual/backends/pygletbackend.py +970 -0
- psychopy/visual/basevisual.py +2027 -0
- psychopy/visual/brush.py +204 -0
- psychopy/visual/bufferimage.py +311 -0
- psychopy/visual/button.py +194 -0
- psychopy/visual/circle.py +165 -0
- psychopy/visual/custommouse.py +263 -0
- psychopy/visual/dot.py +734 -0
- psychopy/visual/dropdown.py +165 -0
- psychopy/visual/elementarray.py +802 -0
- psychopy/visual/filters.py +419 -0
- psychopy/visual/form.py +1195 -0
- psychopy/visual/globalVars.py +24 -0
- psychopy/visual/grating.py +581 -0
- psychopy/visual/helpers.py +336 -0
- psychopy/visual/image.py +438 -0
- psychopy/visual/line.py +227 -0
- psychopy/visual/movie.py +12 -0
- psychopy/visual/movie2.py +21 -0
- psychopy/visual/movie3.py +18 -0
- psychopy/visual/movies/__init__.py +2334 -0
- psychopy/visual/movies/frame.py +258 -0
- psychopy/visual/movies/metadata.py +242 -0
- psychopy/visual/movies/players/_base.py +364 -0
- psychopy/visual/nnlvs.py +830 -0
- psychopy/visual/noise.py +32 -0
- psychopy/visual/panorama.py +313 -0
- psychopy/visual/patch.py +21 -0
- psychopy/visual/pie.py +237 -0
- psychopy/visual/polygon.py +226 -0
- psychopy/visual/progress.py +313 -0
- psychopy/visual/radial.py +29 -0
- psychopy/visual/ratingscale.py +18 -0
- psychopy/visual/rect.py +195 -0
- psychopy/visual/rift.py +2660 -0
- psychopy/visual/roi.py +141 -0
- psychopy/visual/secondorder.py +27 -0
- psychopy/visual/shaders.py +787 -0
- psychopy/visual/shape.py +897 -0
- psychopy/visual/simpleimage.py +303 -0
- psychopy/visual/slider.py +1222 -0
- psychopy/visual/stim3d.py +2109 -0
- psychopy/visual/target.py +278 -0
- psychopy/visual/text.py +769 -0
- psychopy/visual/textbox/__init__.py +1280 -0
- psychopy/visual/textbox/fontmanager.py +574 -0
- psychopy/visual/textbox/parsedtext.py +317 -0
- psychopy/visual/textbox/textgrid.py +278 -0
- psychopy/visual/textbox/textureatlas.py +248 -0
- psychopy/visual/textbox2/__init__.py +4 -0
- psychopy/visual/textbox2/textbox2.py +1970 -0
- psychopy/visual/vlcmoviestim.py +1294 -0
- psychopy/visual/window.py +3910 -0
- psychopy/visual/windowframepack.py +86 -0
- psychopy/visual/windowwarp.py +457 -0
- psychopy/voicekey/__init__.py +56 -0
- psychopy/voicekey/labjack_vks.py +9 -0
- psychopy/voicekey/parallel_vks.py +9 -0
- psychopy/voicekey/vk_tools.py +131 -0
- psychopy/web.py +289 -0
- psychopy-2025.2.4.dist-info/METADATA +160 -0
- psychopy-2025.2.4.dist-info/RECORD +3127 -0
- psychopy-2025.2.4.dist-info/WHEEL +4 -0
- psychopy-2025.2.4.dist-info/entry_points.txt +5 -0
- psychopy-2025.2.4.dist-info/licenses/LICENSE +674 -0
psychopy/data/trial.py
ADDED
|
@@ -0,0 +1,2505 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import copy
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pandas as pd
|
|
10
|
+
|
|
11
|
+
from psychopy import logging, constants
|
|
12
|
+
from psychopy.tools.filetools import (openOutputFile, genDelimiter,
|
|
13
|
+
genFilenameFromDelimiter)
|
|
14
|
+
from .utils import importConditions
|
|
15
|
+
from .base import _BaseTrialHandler, DataHandler
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TrialType(dict):
|
|
19
|
+
"""This is just like a dict, except that you can access keys with obj.key
|
|
20
|
+
"""
|
|
21
|
+
def __getattribute__(self, name):
|
|
22
|
+
try: # to get attr from dict in normal way (passing self)
|
|
23
|
+
return dict.__getattribute__(self, name)
|
|
24
|
+
except AttributeError:
|
|
25
|
+
try:
|
|
26
|
+
return self[name]
|
|
27
|
+
except KeyError:
|
|
28
|
+
msg = "TrialType has no attribute (or key) \'%s\'"
|
|
29
|
+
raise AttributeError(msg % name)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TrialHandler(_BaseTrialHandler):
|
|
33
|
+
"""Class to handle trial sequencing and data storage.
|
|
34
|
+
|
|
35
|
+
Calls to .next() will fetch the next trial object given to this handler,
|
|
36
|
+
according to the method specified (random, sequential, fullRandom).
|
|
37
|
+
Calls will raise a StopIteration error if trials have finished.
|
|
38
|
+
|
|
39
|
+
See demo_trialHandler.py
|
|
40
|
+
|
|
41
|
+
The psydat file format is literally just a pickled copy of the
|
|
42
|
+
TrialHandler object that saved it. You can open it with::
|
|
43
|
+
|
|
44
|
+
from psychopy.tools.filetools import fromFile
|
|
45
|
+
dat = fromFile(path)
|
|
46
|
+
|
|
47
|
+
Then you'll find that `dat` has the following attributes that
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self,
|
|
51
|
+
trialList,
|
|
52
|
+
nReps,
|
|
53
|
+
method='random',
|
|
54
|
+
dataTypes=None,
|
|
55
|
+
extraInfo=None,
|
|
56
|
+
seed=None,
|
|
57
|
+
originPath=None,
|
|
58
|
+
name='',
|
|
59
|
+
autoLog=True):
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
:Parameters:
|
|
63
|
+
|
|
64
|
+
trialList: a simple list (or flat array) of dictionaries
|
|
65
|
+
specifying conditions. This can be imported from an
|
|
66
|
+
excel/csv file using :func:`~psychopy.data.importConditions`
|
|
67
|
+
|
|
68
|
+
nReps: number of repeats for all conditions
|
|
69
|
+
|
|
70
|
+
method: *'random',* 'sequential', or 'fullRandom'
|
|
71
|
+
'sequential' obviously presents the conditions in the order
|
|
72
|
+
they appear in the list. 'random' will result in a shuffle
|
|
73
|
+
of the conditions on each repeat, but all conditions
|
|
74
|
+
occur once before the second repeat etc. 'fullRandom'
|
|
75
|
+
fully randomises the trials across repeats as well,
|
|
76
|
+
which means you could potentially run all trials of
|
|
77
|
+
one condition before any trial of another.
|
|
78
|
+
|
|
79
|
+
dataTypes: (optional) list of names for data storage.
|
|
80
|
+
e.g. ['corr','rt','resp']. If not provided then these
|
|
81
|
+
will be created as needed during calls to
|
|
82
|
+
:func:`~psychopy.data.TrialHandler.addData`
|
|
83
|
+
|
|
84
|
+
extraInfo: A dictionary
|
|
85
|
+
This will be stored alongside the data and usually
|
|
86
|
+
describes the experiment and subject ID, date etc.
|
|
87
|
+
|
|
88
|
+
seed: an integer
|
|
89
|
+
If provided then this fixes the random number generator to
|
|
90
|
+
use the same pattern of trials, by seeding its startpoint
|
|
91
|
+
|
|
92
|
+
originPath: a string describing the location of the
|
|
93
|
+
script / experiment file path. The psydat file format will
|
|
94
|
+
store a copy of the experiment if possible. If
|
|
95
|
+
`originPath==None` is provided here then the TrialHandler
|
|
96
|
+
will still store a copy of the script where it was
|
|
97
|
+
created. If `OriginPath==-1` then nothing will be stored.
|
|
98
|
+
|
|
99
|
+
:Attributes (after creation):
|
|
100
|
+
|
|
101
|
+
.data - a dictionary (or more strictly, a `DataHandler` sub-
|
|
102
|
+
class of a dictionary) of numpy arrays, one for each data
|
|
103
|
+
type stored
|
|
104
|
+
|
|
105
|
+
.trialList - the original list of dicts, specifying the conditions
|
|
106
|
+
|
|
107
|
+
.thisIndex - the index of the current trial in the original
|
|
108
|
+
conditions list
|
|
109
|
+
|
|
110
|
+
.nTotal - the total number of trials that will be run
|
|
111
|
+
|
|
112
|
+
.nRemaining - the total number of trials remaining
|
|
113
|
+
|
|
114
|
+
.thisN - total trials completed so far
|
|
115
|
+
|
|
116
|
+
.thisRepN - which repeat you are currently on
|
|
117
|
+
|
|
118
|
+
.thisTrialN - which trial number *within* that repeat
|
|
119
|
+
|
|
120
|
+
.thisTrial - a dictionary giving the parameters of the current
|
|
121
|
+
trial
|
|
122
|
+
|
|
123
|
+
.finished - True/False for have we finished yet
|
|
124
|
+
|
|
125
|
+
.extraInfo - the dictionary of extra info as given at beginning
|
|
126
|
+
|
|
127
|
+
.origin - the contents of the script or builder experiment that
|
|
128
|
+
created the handler
|
|
129
|
+
|
|
130
|
+
"""
|
|
131
|
+
self.name = name
|
|
132
|
+
self.autoLog = autoLog
|
|
133
|
+
|
|
134
|
+
if trialList in (None, []): # user wants an empty trialList
|
|
135
|
+
# which corresponds to a list with a single empty entry
|
|
136
|
+
self.trialList = [None]
|
|
137
|
+
# user has hopefully specified a filename
|
|
138
|
+
elif isinstance(trialList, str) and os.path.isfile(trialList):
|
|
139
|
+
# import conditions from that file
|
|
140
|
+
self.trialList = importConditions(trialList)
|
|
141
|
+
else:
|
|
142
|
+
self.trialList = trialList
|
|
143
|
+
# convert any entry in the TrialList into a TrialType object (with
|
|
144
|
+
# obj.key or obj[key] access)
|
|
145
|
+
for n, entry in enumerate(self.trialList):
|
|
146
|
+
if type(entry) == dict:
|
|
147
|
+
self.trialList[n] = TrialType(entry)
|
|
148
|
+
self.nReps = int(nReps)
|
|
149
|
+
self.nTotal = self.nReps * len(self.trialList)
|
|
150
|
+
self.nRemaining = self.nTotal # subtract 1 each trial
|
|
151
|
+
self.method = method
|
|
152
|
+
self.thisRepN = 0 # records which repetition or pass we are on
|
|
153
|
+
self.thisTrialN = -1 # records trial number within this repetition
|
|
154
|
+
self.thisN = -1
|
|
155
|
+
self.thisIndex = 0 # index of current trial in the conditions list
|
|
156
|
+
self.thisTrial = []
|
|
157
|
+
self.finished = False
|
|
158
|
+
self.extraInfo = extraInfo
|
|
159
|
+
self.seed = seed
|
|
160
|
+
# create dataHandler
|
|
161
|
+
self.data = DataHandler(trials=self)
|
|
162
|
+
if dataTypes != None:
|
|
163
|
+
self.data.addDataType(dataTypes)
|
|
164
|
+
self.data.addDataType('ran')
|
|
165
|
+
self.data['ran'].mask = False # this is a bool; all entries are valid
|
|
166
|
+
self.data.addDataType('order')
|
|
167
|
+
# generate stimulus sequence
|
|
168
|
+
if self.method in ['random', 'sequential', 'fullRandom']:
|
|
169
|
+
self.sequenceIndices = self._createSequence()
|
|
170
|
+
else:
|
|
171
|
+
self.sequenceIndices = []
|
|
172
|
+
|
|
173
|
+
self.originPath, self.origin = self.getOriginPathAndFile(originPath)
|
|
174
|
+
self._exp = None # the experiment handler that owns me!
|
|
175
|
+
# starting status
|
|
176
|
+
self.status = constants.NOT_STARTED
|
|
177
|
+
|
|
178
|
+
def __iter__(self):
|
|
179
|
+
return self
|
|
180
|
+
|
|
181
|
+
def __repr__(self):
|
|
182
|
+
"""prints a more verbose version of self as string
|
|
183
|
+
"""
|
|
184
|
+
return self.__str__(verbose=True)
|
|
185
|
+
|
|
186
|
+
def __str__(self, verbose=False):
|
|
187
|
+
"""string representation of the object
|
|
188
|
+
"""
|
|
189
|
+
strRepres = 'psychopy.data.{}(\n'.format(self.__class__.__name__)
|
|
190
|
+
attribs = dir(self)
|
|
191
|
+
|
|
192
|
+
# data first, then all others
|
|
193
|
+
try:
|
|
194
|
+
data = self.data
|
|
195
|
+
except Exception:
|
|
196
|
+
data = None
|
|
197
|
+
if data:
|
|
198
|
+
strRepres += str('\tdata=')
|
|
199
|
+
strRepres += str(data) + '\n'
|
|
200
|
+
|
|
201
|
+
method_string = "<class 'method'>"
|
|
202
|
+
|
|
203
|
+
for thisAttrib in attribs:
|
|
204
|
+
# can handle each attribute differently
|
|
205
|
+
if method_string in str(type(getattr(self, thisAttrib))):
|
|
206
|
+
# this is a method
|
|
207
|
+
continue
|
|
208
|
+
elif thisAttrib[0] == '_':
|
|
209
|
+
# the attrib is private
|
|
210
|
+
continue
|
|
211
|
+
elif thisAttrib == 'data':
|
|
212
|
+
# we handled this first
|
|
213
|
+
continue
|
|
214
|
+
elif len(str(getattr(self, thisAttrib))) > 20 and not verbose:
|
|
215
|
+
# just give type of LONG public attribute
|
|
216
|
+
strRepres += str('\t' + thisAttrib + '=')
|
|
217
|
+
strRepres += str(type(getattr(self, thisAttrib))) + '\n'
|
|
218
|
+
else:
|
|
219
|
+
# give the complete contents of attribute
|
|
220
|
+
strRepres += str('\t' + thisAttrib + '=')
|
|
221
|
+
strRepres += str(getattr(self, thisAttrib)) + '\n'
|
|
222
|
+
|
|
223
|
+
strRepres += ')'
|
|
224
|
+
return strRepres
|
|
225
|
+
|
|
226
|
+
def _createSequence(self):
|
|
227
|
+
"""Pre-generates the sequence of trial presentations
|
|
228
|
+
(for non-adaptive methods). This is called automatically when
|
|
229
|
+
the TrialHandler is initialised so doesn't need an explicit call
|
|
230
|
+
from the user.
|
|
231
|
+
|
|
232
|
+
The returned sequence has form indices[stimN][repN]
|
|
233
|
+
Example: sequential with 6 trialtypes (rows), 5 reps (cols), returns::
|
|
234
|
+
|
|
235
|
+
[[0 0 0 0 0]
|
|
236
|
+
[1 1 1 1 1]
|
|
237
|
+
[2 2 2 2 2]
|
|
238
|
+
[3 3 3 3 3]
|
|
239
|
+
[4 4 4 4 4]
|
|
240
|
+
[5 5 5 5 5]]
|
|
241
|
+
|
|
242
|
+
These 30 trials will be returned by .next() in the order:
|
|
243
|
+
0, 1, 2, 3, 4, 5, 0, 1, 2, ... ... 3, 4, 5
|
|
244
|
+
|
|
245
|
+
To add a new type of sequence (as of v1.65.02):
|
|
246
|
+
- add the sequence generation code here
|
|
247
|
+
- adjust "if self.method in [ ...]:" in both __init__ and .next()
|
|
248
|
+
- adjust allowedVals in experiment.py -> shows up in DlgLoopProperties
|
|
249
|
+
Note that users can make any sequence whatsoever outside of PsychoPy,
|
|
250
|
+
and specify sequential order; any order is possible this way.
|
|
251
|
+
"""
|
|
252
|
+
# create indices for a single rep
|
|
253
|
+
indices = np.asarray(self._makeIndices(self.trialList), dtype=int)
|
|
254
|
+
|
|
255
|
+
rng = np.random.default_rng(seed=self.seed)
|
|
256
|
+
if self.method == 'random':
|
|
257
|
+
sequenceIndices = []
|
|
258
|
+
for thisRep in range(self.nReps):
|
|
259
|
+
thisRepSeq = rng.permutation(indices.flat).tolist()
|
|
260
|
+
sequenceIndices.append(thisRepSeq)
|
|
261
|
+
sequenceIndices = np.transpose(sequenceIndices)
|
|
262
|
+
elif self.method == 'sequential':
|
|
263
|
+
sequenceIndices = np.repeat(indices, self.nReps, 1)
|
|
264
|
+
elif self.method == 'fullRandom':
|
|
265
|
+
# indices*nReps, flatten, shuffle, unflatten; only use seed once
|
|
266
|
+
sequential = np.repeat(indices, self.nReps, 1) # = sequential
|
|
267
|
+
randomFlat = rng.permutation(sequential.flat)
|
|
268
|
+
sequenceIndices = np.reshape(
|
|
269
|
+
randomFlat, (len(indices), self.nReps))
|
|
270
|
+
if self.autoLog:
|
|
271
|
+
msg = 'Created sequence: %s, trialTypes=%d, nReps=%i, seed=%s'
|
|
272
|
+
vals = (self.method, len(indices), self.nReps, str(self.seed))
|
|
273
|
+
logging.exp(msg % vals)
|
|
274
|
+
return sequenceIndices
|
|
275
|
+
|
|
276
|
+
def _makeIndices(self, inputArray):
|
|
277
|
+
"""
|
|
278
|
+
Creates an array of tuples the same shape as the input array
|
|
279
|
+
where each tuple contains the indices to itself in the array.
|
|
280
|
+
|
|
281
|
+
Useful for shuffling and then using as a reference.
|
|
282
|
+
"""
|
|
283
|
+
# make sure its an array of objects (can be strings etc)
|
|
284
|
+
inputArray = np.asarray(inputArray, 'O')
|
|
285
|
+
# get some simple variables for later
|
|
286
|
+
dims = inputArray.shape
|
|
287
|
+
dimsProd = np.prod(dims)
|
|
288
|
+
dimsN = len(dims)
|
|
289
|
+
dimsList = list(range(dimsN))
|
|
290
|
+
listOfLists = []
|
|
291
|
+
# this creates space for an array of any objects
|
|
292
|
+
arrayOfTuples = np.ones(dimsProd, 'O')
|
|
293
|
+
|
|
294
|
+
# for each dimension create list of its indices (using modulo)
|
|
295
|
+
for thisDim in dimsList:
|
|
296
|
+
prevDimsProd = np.prod(dims[:thisDim])
|
|
297
|
+
# NB this means modulus in python
|
|
298
|
+
thisDimVals = np.arange(dimsProd) / prevDimsProd % dims[thisDim]
|
|
299
|
+
listOfLists.append(thisDimVals)
|
|
300
|
+
|
|
301
|
+
# convert to array
|
|
302
|
+
indexArr = np.asarray(listOfLists)
|
|
303
|
+
for n in range(dimsProd):
|
|
304
|
+
arrayOfTuples[n] = tuple((indexArr[:, n]))
|
|
305
|
+
return (np.reshape(arrayOfTuples, dims)).tolist()
|
|
306
|
+
|
|
307
|
+
def __next__(self):
|
|
308
|
+
"""Advances to next trial and returns it.
|
|
309
|
+
Updates attributes; thisTrial, thisTrialN and thisIndex
|
|
310
|
+
If the trials have ended this method will raise a StopIteration error.
|
|
311
|
+
This can be handled with code such as::
|
|
312
|
+
|
|
313
|
+
trials = data.TrialHandler(.......)
|
|
314
|
+
for eachTrial in trials: # automatically stops when done
|
|
315
|
+
# do stuff
|
|
316
|
+
|
|
317
|
+
or::
|
|
318
|
+
|
|
319
|
+
trials = data.TrialHandler(.......)
|
|
320
|
+
while True: # ie forever
|
|
321
|
+
try:
|
|
322
|
+
thisTrial = trials.next()
|
|
323
|
+
except StopIteration: # we got a StopIteration error
|
|
324
|
+
break #break out of the forever loop
|
|
325
|
+
# do stuff here for the trial
|
|
326
|
+
"""
|
|
327
|
+
# update pointer for next trials
|
|
328
|
+
self.thisTrialN += 1 # number of trial this pass
|
|
329
|
+
self.thisN += 1 # number of trial in total
|
|
330
|
+
self.nRemaining -= 1
|
|
331
|
+
if self.thisTrialN == len(self.trialList):
|
|
332
|
+
# start a new repetition
|
|
333
|
+
self.thisTrialN = 0
|
|
334
|
+
self.thisRepN += 1
|
|
335
|
+
if self.thisRepN >= self.nReps:
|
|
336
|
+
# all reps complete
|
|
337
|
+
self.thisTrial = []
|
|
338
|
+
self.finished = True
|
|
339
|
+
|
|
340
|
+
if self.finished == True:
|
|
341
|
+
self._terminate()
|
|
342
|
+
|
|
343
|
+
# fetch the trial info
|
|
344
|
+
if self.method in ('random', 'sequential', 'fullRandom'):
|
|
345
|
+
self.thisIndex = self.sequenceIndices[
|
|
346
|
+
self.thisTrialN][self.thisRepN]
|
|
347
|
+
self.thisTrial = self.trialList[self.thisIndex]
|
|
348
|
+
self.data.add('ran', 1)
|
|
349
|
+
self.data.add('order', self.thisN)
|
|
350
|
+
if self.autoLog:
|
|
351
|
+
msg = 'New trial (rep=%i, index=%i): %s'
|
|
352
|
+
vals = (self.thisRepN, self.thisTrialN, self.thisTrial)
|
|
353
|
+
logging.exp(msg % vals, obj=self.thisTrial)
|
|
354
|
+
return self.thisTrial
|
|
355
|
+
|
|
356
|
+
next = __next__ # allows user to call without a loop `val = trials.next()`
|
|
357
|
+
|
|
358
|
+
def getCurrentTrial(self):
|
|
359
|
+
"""Returns the condition for the current trial, without
|
|
360
|
+
advancing the trials.
|
|
361
|
+
"""
|
|
362
|
+
return self.trialList[self.thisIndex]
|
|
363
|
+
|
|
364
|
+
def getFutureTrial(self, n=1):
|
|
365
|
+
"""Returns the condition for n trials into the future,
|
|
366
|
+
without advancing the trials. A negative n returns a previous (past)
|
|
367
|
+
trial. Returns 'None' if attempting to go beyond the last trial.
|
|
368
|
+
"""
|
|
369
|
+
# check that we don't go out of bounds for either positive or negative
|
|
370
|
+
if n > self.nRemaining or self.thisN + n < 0:
|
|
371
|
+
return None
|
|
372
|
+
seqs = np.array(self.sequenceIndices).transpose().flat
|
|
373
|
+
condIndex = seqs[self.thisN + n]
|
|
374
|
+
return self.trialList[condIndex]
|
|
375
|
+
|
|
376
|
+
def getEarlierTrial(self, n=-1):
|
|
377
|
+
"""Returns the condition information from n trials previously.
|
|
378
|
+
Useful for comparisons in n-back tasks. Returns 'None' if trying
|
|
379
|
+
to access a trial prior to the first.
|
|
380
|
+
"""
|
|
381
|
+
# treat positive offset values as equivalent to negative ones:
|
|
382
|
+
return self.getFutureTrial(-abs(n))
|
|
383
|
+
|
|
384
|
+
def _createOutputArray(self, stimOut, dataOut, delim=None,
|
|
385
|
+
matrixOnly=False):
|
|
386
|
+
"""Does the leg-work for saveAsText and saveAsExcel.
|
|
387
|
+
Combines stimOut with ._parseDataOutput()
|
|
388
|
+
"""
|
|
389
|
+
if (stimOut == [] and
|
|
390
|
+
len(self.trialList) and
|
|
391
|
+
hasattr(self.trialList[0], 'keys')):
|
|
392
|
+
stimOut = list(self.trialList[0].keys())
|
|
393
|
+
# these get added somewhere (by DataHandler?)
|
|
394
|
+
if 'n' in stimOut:
|
|
395
|
+
stimOut.remove('n')
|
|
396
|
+
if 'float' in stimOut:
|
|
397
|
+
stimOut.remove('float')
|
|
398
|
+
|
|
399
|
+
lines = []
|
|
400
|
+
# parse the dataout section of the output
|
|
401
|
+
dataOut, dataAnal, dataHead = self._createOutputArrayData(dataOut)
|
|
402
|
+
if not matrixOnly:
|
|
403
|
+
thisLine = []
|
|
404
|
+
lines.append(thisLine)
|
|
405
|
+
# write a header line
|
|
406
|
+
for heading in list(stimOut) + dataHead:
|
|
407
|
+
if heading == 'ran_sum':
|
|
408
|
+
heading = 'n'
|
|
409
|
+
elif heading == 'order_raw':
|
|
410
|
+
heading = 'order'
|
|
411
|
+
thisLine.append(heading)
|
|
412
|
+
|
|
413
|
+
# loop through stimuli, writing data
|
|
414
|
+
for stimN in range(len(self.trialList)):
|
|
415
|
+
thisLine = []
|
|
416
|
+
lines.append(thisLine)
|
|
417
|
+
# first the params for this stim (from self.trialList)
|
|
418
|
+
for heading in stimOut:
|
|
419
|
+
thisLine.append(self.trialList[stimN][heading])
|
|
420
|
+
|
|
421
|
+
# then the data for this stim (from self.data)
|
|
422
|
+
for thisDataOut in dataOut:
|
|
423
|
+
# make a string version of the data and then format it
|
|
424
|
+
tmpData = dataAnal[thisDataOut][stimN]
|
|
425
|
+
replaceNone = False
|
|
426
|
+
if hasattr(tmpData, 'tolist'): # is a numpy array
|
|
427
|
+
strVersion = str(tmpData.tolist())
|
|
428
|
+
# for numeric data replace None with a blank cell
|
|
429
|
+
if tmpData.dtype.kind not in 'SaUV':
|
|
430
|
+
replaceNone = True
|
|
431
|
+
strVersion = strVersion.replace('None', '')
|
|
432
|
+
elif tmpData in [None, 'None']:
|
|
433
|
+
strVersion = ''
|
|
434
|
+
else:
|
|
435
|
+
strVersion = str(tmpData)
|
|
436
|
+
|
|
437
|
+
if strVersion == '()':
|
|
438
|
+
# 'no data' in masked array should show as "--"
|
|
439
|
+
strVersion = "--"
|
|
440
|
+
# handle list of values (e.g. rt_raw )
|
|
441
|
+
if (len(strVersion) and
|
|
442
|
+
strVersion[0] in '[(' and
|
|
443
|
+
strVersion[-1] in '])'):
|
|
444
|
+
strVersion = strVersion[1:-1] # skip first and last chars
|
|
445
|
+
# handle lists of lists (e.g. raw of multiple key presses)
|
|
446
|
+
if (len(strVersion) and
|
|
447
|
+
strVersion[0] in '[(' and
|
|
448
|
+
strVersion[-1] in '])'):
|
|
449
|
+
if replaceNone:
|
|
450
|
+
# Add None back so that the str is valid for eval
|
|
451
|
+
strVersion = strVersion.replace('[,', '[None,')
|
|
452
|
+
strVersion = strVersion.replace(', ,', ', None,')
|
|
453
|
+
tup = eval(strVersion) # convert back to a tuple
|
|
454
|
+
for entry in tup:
|
|
455
|
+
# contents of each entry is a list or tuple so keep in
|
|
456
|
+
# quotes to avoid probs with delim
|
|
457
|
+
currentEntry = str(entry)
|
|
458
|
+
if replaceNone:
|
|
459
|
+
currentEntry = currentEntry.replace('None', '')
|
|
460
|
+
thisLine.append(currentEntry)
|
|
461
|
+
else:
|
|
462
|
+
thisLine.extend(strVersion.split(','))
|
|
463
|
+
|
|
464
|
+
# add self.extraInfo
|
|
465
|
+
if (self.extraInfo != None) and not matrixOnly:
|
|
466
|
+
lines.append([])
|
|
467
|
+
# give a single line of space and then a heading
|
|
468
|
+
lines.append(['extraInfo'])
|
|
469
|
+
for key, value in list(self.extraInfo.items()):
|
|
470
|
+
lines.append([key, value])
|
|
471
|
+
return lines
|
|
472
|
+
|
|
473
|
+
def _createOutputArrayData(self, dataOut):
|
|
474
|
+
"""This just creates the dataOut part of the output matrix.
|
|
475
|
+
It is called by _createOutputArray() which creates the header
|
|
476
|
+
line and adds the stimOut columns
|
|
477
|
+
"""
|
|
478
|
+
dataHead = [] # will store list of data headers
|
|
479
|
+
dataAnal = dict([]) # will store data that has been analyzed
|
|
480
|
+
if type(dataOut) == str:
|
|
481
|
+
# don't do list convert or we get a list of letters
|
|
482
|
+
dataOut = [dataOut]
|
|
483
|
+
elif type(dataOut) != list:
|
|
484
|
+
dataOut = list(dataOut)
|
|
485
|
+
|
|
486
|
+
# expand any 'all' dataTypes to be full list of available dataTypes
|
|
487
|
+
allDataTypes = list(self.data.keys())
|
|
488
|
+
# treat these separately later
|
|
489
|
+
allDataTypes.remove('ran')
|
|
490
|
+
# ready to go through standard data types
|
|
491
|
+
dataOutNew = []
|
|
492
|
+
for thisDataOut in dataOut:
|
|
493
|
+
if thisDataOut == 'n':
|
|
494
|
+
# n is really just the sum of the ran trials
|
|
495
|
+
dataOutNew.append('ran_sum')
|
|
496
|
+
continue # no need to do more with this one
|
|
497
|
+
# then break into dataType and analysis
|
|
498
|
+
dataType, analType = thisDataOut.rsplit('_', 1)
|
|
499
|
+
if dataType == 'all':
|
|
500
|
+
dataOutNew.extend(
|
|
501
|
+
[key + "_" + analType for key in allDataTypes])
|
|
502
|
+
if 'order_mean' in dataOutNew:
|
|
503
|
+
dataOutNew.remove('order_mean')
|
|
504
|
+
if 'order_std' in dataOutNew:
|
|
505
|
+
dataOutNew.remove('order_std')
|
|
506
|
+
else:
|
|
507
|
+
dataOutNew.append(thisDataOut)
|
|
508
|
+
dataOut = dataOutNew
|
|
509
|
+
# sort so all datatypes come together, rather than all analtypes
|
|
510
|
+
dataOut.sort()
|
|
511
|
+
|
|
512
|
+
# do the various analyses, keeping track of fails (e.g. mean of a
|
|
513
|
+
# string)
|
|
514
|
+
dataOutInvalid = []
|
|
515
|
+
# add back special data types (n and order)
|
|
516
|
+
if 'ran_sum' in dataOut:
|
|
517
|
+
# move n to the first column
|
|
518
|
+
dataOut.remove('ran_sum')
|
|
519
|
+
dataOut.insert(0, 'ran_sum')
|
|
520
|
+
if 'order_raw' in dataOut:
|
|
521
|
+
# move order_raw to the second column
|
|
522
|
+
dataOut.remove('order_raw')
|
|
523
|
+
dataOut.append('order_raw')
|
|
524
|
+
# do the necessary analysis on the data
|
|
525
|
+
for thisDataOutN, thisDataOut in enumerate(dataOut):
|
|
526
|
+
dataType, analType = thisDataOut.rsplit('_', 1)
|
|
527
|
+
if not dataType in self.data:
|
|
528
|
+
# that analysis can't be done
|
|
529
|
+
dataOutInvalid.append(thisDataOut)
|
|
530
|
+
continue
|
|
531
|
+
thisData = self.data[dataType]
|
|
532
|
+
|
|
533
|
+
# set the header
|
|
534
|
+
dataHead.append(dataType + '_' + analType)
|
|
535
|
+
# analyse thisData using numpy module
|
|
536
|
+
if analType in dir(np):
|
|
537
|
+
try:
|
|
538
|
+
# will fail if we try to take mean of a string for example
|
|
539
|
+
if analType == 'std':
|
|
540
|
+
thisAnal = np.std(thisData, axis=1, ddof=0)
|
|
541
|
+
# normalise by N-1 instead. This should work by
|
|
542
|
+
# setting ddof=1 but doesn't as of 08/2010 (because
|
|
543
|
+
# of using a masked array?)
|
|
544
|
+
N = thisData.shape[1]
|
|
545
|
+
if N == 1:
|
|
546
|
+
thisAnal *= 0 # prevent a divide-by-zero error
|
|
547
|
+
else:
|
|
548
|
+
sqrt = np.sqrt
|
|
549
|
+
thisAnal = thisAnal * sqrt(N) / sqrt(N - 1)
|
|
550
|
+
else:
|
|
551
|
+
thisAnal = eval("np.%s(thisData,1)" % analType)
|
|
552
|
+
except Exception:
|
|
553
|
+
# that analysis doesn't work
|
|
554
|
+
dataHead.remove(dataType + '_' + analType)
|
|
555
|
+
dataOutInvalid.append(thisDataOut)
|
|
556
|
+
continue # to next analysis
|
|
557
|
+
elif analType == 'raw':
|
|
558
|
+
thisAnal = thisData
|
|
559
|
+
else:
|
|
560
|
+
raise AttributeError('You can only use analyses from numpy')
|
|
561
|
+
# add extra cols to header if necess
|
|
562
|
+
if len(thisAnal.shape) > 1:
|
|
563
|
+
for n in range(thisAnal.shape[1] - 1):
|
|
564
|
+
dataHead.append("")
|
|
565
|
+
dataAnal[thisDataOut] = thisAnal
|
|
566
|
+
|
|
567
|
+
# remove invalid analyses (e.g. average of a string)
|
|
568
|
+
for invalidAnal in dataOutInvalid:
|
|
569
|
+
dataOut.remove(invalidAnal)
|
|
570
|
+
return dataOut, dataAnal, dataHead
|
|
571
|
+
|
|
572
|
+
def saveAsWideText(self, fileName,
|
|
573
|
+
delim=None,
|
|
574
|
+
matrixOnly=False,
|
|
575
|
+
appendFile=True,
|
|
576
|
+
encoding='utf-8-sig',
|
|
577
|
+
fileCollisionMethod='rename'):
|
|
578
|
+
"""Write a text file with the session, stimulus, and data values
|
|
579
|
+
from each trial in chronological order. Also, return a
|
|
580
|
+
pandas DataFrame containing same information as the file.
|
|
581
|
+
|
|
582
|
+
That is, unlike 'saveAsText' and 'saveAsExcel':
|
|
583
|
+
- each row comprises information from only a single trial.
|
|
584
|
+
- no summarizing is done (such as collapsing to produce mean and
|
|
585
|
+
standard deviation values across trials).
|
|
586
|
+
|
|
587
|
+
This 'wide' format, as expected by R for creating dataframes, and
|
|
588
|
+
various other analysis programs, means that some information must
|
|
589
|
+
be repeated on every row.
|
|
590
|
+
|
|
591
|
+
In particular, if the trialHandler's 'extraInfo' exists, then each
|
|
592
|
+
entry in there occurs in every row. In builder, this will include
|
|
593
|
+
any entries in the 'Experiment info' field of the
|
|
594
|
+
'Experiment settings' dialog. In Coder, this information can be
|
|
595
|
+
set using something like::
|
|
596
|
+
|
|
597
|
+
myTrialHandler.extraInfo = {'SubjID': 'Joan Smith',
|
|
598
|
+
'Group': 'Control'}
|
|
599
|
+
|
|
600
|
+
:Parameters:
|
|
601
|
+
|
|
602
|
+
fileName:
|
|
603
|
+
if extension is not specified, '.csv' will be appended
|
|
604
|
+
if the delimiter is ',', else '.tsv' will be appended.
|
|
605
|
+
Can include path info.
|
|
606
|
+
|
|
607
|
+
delim:
|
|
608
|
+
allows the user to use a delimiter other than the default
|
|
609
|
+
tab ("," is popular with file extension ".csv")
|
|
610
|
+
|
|
611
|
+
matrixOnly:
|
|
612
|
+
outputs the data with no header row.
|
|
613
|
+
|
|
614
|
+
appendFile:
|
|
615
|
+
will add this output to the end of the specified file if
|
|
616
|
+
it already exists.
|
|
617
|
+
|
|
618
|
+
fileCollisionMethod:
|
|
619
|
+
Collision method passed to
|
|
620
|
+
:func:`~psychopy.tools.fileerrortools.handleFileCollision`
|
|
621
|
+
|
|
622
|
+
encoding:
|
|
623
|
+
The encoding to use when saving a the file.
|
|
624
|
+
Defaults to `utf-8-sig`.
|
|
625
|
+
|
|
626
|
+
"""
|
|
627
|
+
if self.thisTrialN < 0 and self.thisRepN < 0:
|
|
628
|
+
# if both are < 1 we haven't started
|
|
629
|
+
logging.info('TrialHandler.saveAsWideText called but no '
|
|
630
|
+
'trials completed. Nothing saved')
|
|
631
|
+
return -1
|
|
632
|
+
|
|
633
|
+
# set default delimiter if none given
|
|
634
|
+
if delim is None:
|
|
635
|
+
delim = genDelimiter(fileName)
|
|
636
|
+
|
|
637
|
+
# create the file or send to stdout
|
|
638
|
+
fileName = genFilenameFromDelimiter(fileName, delim)
|
|
639
|
+
f = openOutputFile(fileName, append=appendFile,
|
|
640
|
+
fileCollisionMethod=fileCollisionMethod,
|
|
641
|
+
encoding=encoding)
|
|
642
|
+
|
|
643
|
+
# collect parameter names related to the stimuli:
|
|
644
|
+
if self.trialList[0]:
|
|
645
|
+
header = list(self.trialList[0].keys())
|
|
646
|
+
else:
|
|
647
|
+
header = []
|
|
648
|
+
# and then add parameter names related to data (e.g. RT)
|
|
649
|
+
header.extend(self.data.dataTypes)
|
|
650
|
+
# get the extra 'wide' parameter names into the header line:
|
|
651
|
+
header.insert(0, "TrialNumber")
|
|
652
|
+
# this is wide format, so we want fixed information
|
|
653
|
+
# (e.g. subject ID, date, etc) repeated every line if it exists:
|
|
654
|
+
if self.extraInfo is not None:
|
|
655
|
+
for key in self.extraInfo:
|
|
656
|
+
header.insert(0, key)
|
|
657
|
+
df = pd.DataFrame(columns=header)
|
|
658
|
+
|
|
659
|
+
# loop through each trial, gathering the actual values:
|
|
660
|
+
dataOut = []
|
|
661
|
+
trialCount = 0
|
|
662
|
+
# total number of trials = number of trialtypes * number of
|
|
663
|
+
# repetitions:
|
|
664
|
+
|
|
665
|
+
repsPerType = {}
|
|
666
|
+
entriesList = []
|
|
667
|
+
for rep in range(self.nReps):
|
|
668
|
+
for trialN in range(len(self.trialList)):
|
|
669
|
+
# find out what trial type was on this trial
|
|
670
|
+
trialTypeIndex = self.sequenceIndices[trialN, rep]
|
|
671
|
+
# determine which repeat it is for this trial
|
|
672
|
+
if trialTypeIndex not in repsPerType:
|
|
673
|
+
repsPerType[trialTypeIndex] = 0
|
|
674
|
+
else:
|
|
675
|
+
repsPerType[trialTypeIndex] += 1
|
|
676
|
+
# what repeat are we on for this trial type?
|
|
677
|
+
trep = repsPerType[trialTypeIndex]
|
|
678
|
+
|
|
679
|
+
# create a dictionary representing each trial:
|
|
680
|
+
nextEntry = {}
|
|
681
|
+
|
|
682
|
+
# add a trial number so the original order of the data can
|
|
683
|
+
# always be recovered if sorted during analysis:
|
|
684
|
+
trialCount += 1
|
|
685
|
+
|
|
686
|
+
# now collect the value from each trial of vars in header:
|
|
687
|
+
for prmName in header:
|
|
688
|
+
# the header includes both trial and data variables, so
|
|
689
|
+
# need to check before accessing:
|
|
690
|
+
tti = trialTypeIndex
|
|
691
|
+
if self.trialList[tti] and prmName in self.trialList[tti]:
|
|
692
|
+
nextEntry[prmName] = self.trialList[tti][prmName]
|
|
693
|
+
elif prmName in self.data:
|
|
694
|
+
nextEntry[prmName] = self.data[prmName][tti][trep]
|
|
695
|
+
elif self.extraInfo != None and prmName in self.extraInfo:
|
|
696
|
+
nextEntry[prmName] = self.extraInfo[prmName]
|
|
697
|
+
else:
|
|
698
|
+
# allow a null value if this parameter wasn't
|
|
699
|
+
# explicitly stored on this trial:
|
|
700
|
+
if prmName == "TrialNumber":
|
|
701
|
+
nextEntry[prmName] = trialCount
|
|
702
|
+
else:
|
|
703
|
+
nextEntry[prmName] = ''
|
|
704
|
+
|
|
705
|
+
# store this trial's data
|
|
706
|
+
dataOut.append(nextEntry)
|
|
707
|
+
# df = df.append(nextEntry, ignore_index=True)
|
|
708
|
+
entriesList.append(nextEntry)
|
|
709
|
+
df = pd.concat([df, pd.DataFrame(entriesList)])
|
|
710
|
+
|
|
711
|
+
if not matrixOnly:
|
|
712
|
+
# write the header row:
|
|
713
|
+
nextLine = ''
|
|
714
|
+
for prmName in header:
|
|
715
|
+
nextLine = nextLine + prmName + delim
|
|
716
|
+
# remove the final orphaned tab character
|
|
717
|
+
f.write(nextLine[:-1] + '\n')
|
|
718
|
+
|
|
719
|
+
# write the data matrix:
|
|
720
|
+
for trial in dataOut:
|
|
721
|
+
nextLine = ''
|
|
722
|
+
for prmName in header:
|
|
723
|
+
nextLine = nextLine + str(trial[prmName]) + delim
|
|
724
|
+
# remove the final orphaned tab character
|
|
725
|
+
nextLine = nextLine[:-1]
|
|
726
|
+
f.write(nextLine + '\n')
|
|
727
|
+
|
|
728
|
+
if f != sys.stdout:
|
|
729
|
+
f.close()
|
|
730
|
+
logging.info('saved wide-format data to %s' % f.name)
|
|
731
|
+
|
|
732
|
+
# Converts numbers to numeric, such as float64, boolean to bool.
|
|
733
|
+
# Otherwise they all are "object" type, i.e. strings
|
|
734
|
+
# df = df.convert_objects()
|
|
735
|
+
return df
|
|
736
|
+
|
|
737
|
+
def saveAsJson(self,
|
|
738
|
+
fileName=None,
|
|
739
|
+
encoding='utf-8',
|
|
740
|
+
fileCollisionMethod='rename'):
|
|
741
|
+
raise NotImplementedError('Not implemented for TrialHandler.')
|
|
742
|
+
|
|
743
|
+
def addData(self, thisType, value, position=None):
|
|
744
|
+
"""Add data for the current trial
|
|
745
|
+
"""
|
|
746
|
+
self.data.add(thisType, value, position=None)
|
|
747
|
+
if self.getExp() != None: # update the experiment handler too
|
|
748
|
+
self.getExp().addData(thisType, value)
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
class Trial(dict):
|
|
752
|
+
def __init__(self, parent, thisN, thisRepN, thisTrialN, thisIndex, data=None):
|
|
753
|
+
dict.__init__(self)
|
|
754
|
+
# TrialHandler containing this trial
|
|
755
|
+
self.parent = parent
|
|
756
|
+
# state information about this trial
|
|
757
|
+
self.thisN = thisN
|
|
758
|
+
self.thisRepN = thisRepN
|
|
759
|
+
self.thisTrialN = thisTrialN
|
|
760
|
+
self.thisIndex = thisIndex
|
|
761
|
+
# add status
|
|
762
|
+
self.status = constants.NOT_STARTED
|
|
763
|
+
# data for this trial
|
|
764
|
+
if data is None:
|
|
765
|
+
data = {}
|
|
766
|
+
else:
|
|
767
|
+
data = data.copy()
|
|
768
|
+
self.data = data
|
|
769
|
+
|
|
770
|
+
def __repr__(self):
|
|
771
|
+
return (
|
|
772
|
+
f"<Trial {self.thisN} ({self.thisTrialN} in rep {self.thisRepN}) "
|
|
773
|
+
f"data={ {key: val for key,val in self.items()} }>"
|
|
774
|
+
)
|
|
775
|
+
|
|
776
|
+
@property
|
|
777
|
+
def data(self):
|
|
778
|
+
# return self when getting data (so it's modified by modifying data)
|
|
779
|
+
return self
|
|
780
|
+
|
|
781
|
+
@data.setter
|
|
782
|
+
def data(self, value: dict):
|
|
783
|
+
# when setting data, clear self...
|
|
784
|
+
self.clear()
|
|
785
|
+
# ... and set each value from the given dict
|
|
786
|
+
for key, val in value.items():
|
|
787
|
+
self[key] = val
|
|
788
|
+
|
|
789
|
+
@property
|
|
790
|
+
def skipped(self):
|
|
791
|
+
"""
|
|
792
|
+
Has this Trial been skipped?
|
|
793
|
+
"""
|
|
794
|
+
return self.data.get('skipped', False)
|
|
795
|
+
|
|
796
|
+
def getDict(self):
|
|
797
|
+
"""
|
|
798
|
+
Get this Trial as a dict.
|
|
799
|
+
|
|
800
|
+
Returns
|
|
801
|
+
-------
|
|
802
|
+
dict
|
|
803
|
+
Dict containing information for this Trial.
|
|
804
|
+
"""
|
|
805
|
+
return {
|
|
806
|
+
'type': "trial_data",
|
|
807
|
+
'thisN': self.thisN,
|
|
808
|
+
'thisRepN': self.thisRepN,
|
|
809
|
+
'thisTrialN': self.thisTrialN,
|
|
810
|
+
'thisIndex': self.thisIndex,
|
|
811
|
+
'data': {key: val for key, val in self.items()},
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
def getJSON(self, asString=False):
|
|
815
|
+
"""
|
|
816
|
+
Serialize this Trial to a JSON format.
|
|
817
|
+
|
|
818
|
+
Parameters
|
|
819
|
+
----------
|
|
820
|
+
asString : bool
|
|
821
|
+
If True, convert the returned object to a string. If False, keep as a dict.
|
|
822
|
+
|
|
823
|
+
Returns
|
|
824
|
+
-------
|
|
825
|
+
str
|
|
826
|
+
The results of Trial.getDict expressed as a JSON string
|
|
827
|
+
"""
|
|
828
|
+
# get self as a dict
|
|
829
|
+
data = self.getDict()
|
|
830
|
+
# convert to string if requested
|
|
831
|
+
if asString:
|
|
832
|
+
data = json.dumps(data)
|
|
833
|
+
|
|
834
|
+
return data
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
class TrialHandler2(_BaseTrialHandler):
|
|
838
|
+
"""Class to handle trial sequencing and data storage.
|
|
839
|
+
|
|
840
|
+
Calls to .next() will fetch the next trial object given to this handler,
|
|
841
|
+
according to the method specified (random, sequential, fullRandom).
|
|
842
|
+
Calls will raise a StopIteration error if trials have finished.
|
|
843
|
+
|
|
844
|
+
See demo_trialHandler.py
|
|
845
|
+
|
|
846
|
+
The psydat file format is literally just a pickled copy of the
|
|
847
|
+
TrialHandler object that saved it. You can open it with::
|
|
848
|
+
|
|
849
|
+
from psychopy.tools.filetools import fromFile
|
|
850
|
+
dat = fromFile(path)
|
|
851
|
+
|
|
852
|
+
Then you'll find that `dat` has the following attributes that
|
|
853
|
+
"""
|
|
854
|
+
|
|
855
|
+
def __init__(
|
|
856
|
+
self,
|
|
857
|
+
trialList,
|
|
858
|
+
nReps,
|
|
859
|
+
method='random',
|
|
860
|
+
dataTypes=None,
|
|
861
|
+
extraInfo=None,
|
|
862
|
+
seed=None,
|
|
863
|
+
originPath=None,
|
|
864
|
+
isTrials=True,
|
|
865
|
+
name='',
|
|
866
|
+
autoLog=True
|
|
867
|
+
):
|
|
868
|
+
"""
|
|
869
|
+
|
|
870
|
+
:Parameters:
|
|
871
|
+
|
|
872
|
+
trialList: filename or a simple list (or flat array) of
|
|
873
|
+
dictionaries specifying conditions
|
|
874
|
+
|
|
875
|
+
nReps: number of repeats for all conditions
|
|
876
|
+
|
|
877
|
+
method: *'random',* 'sequential', or 'fullRandom'
|
|
878
|
+
'sequential' obviously presents the conditions in the order
|
|
879
|
+
they appear in the list. 'random' will result in a shuffle
|
|
880
|
+
of the conditions on each repeat, but all conditions occur
|
|
881
|
+
once before the second repeat etc. 'fullRandom' fully
|
|
882
|
+
randomises the trials across repeats as well, which means
|
|
883
|
+
you could potentially run all trials of one condition
|
|
884
|
+
before any trial of another.
|
|
885
|
+
|
|
886
|
+
dataTypes: (optional) list of names for data storage.
|
|
887
|
+
e.g. ['corr','rt','resp']. If not provided then these
|
|
888
|
+
will be created as needed during calls to
|
|
889
|
+
:func:`~psychopy.data.TrialHandler.addData`
|
|
890
|
+
|
|
891
|
+
extraInfo: A dictionary
|
|
892
|
+
This will be stored alongside the data and usually describes
|
|
893
|
+
the experiment and subject ID, date etc.
|
|
894
|
+
|
|
895
|
+
seed: an integer
|
|
896
|
+
If provided then this fixes the random number generator to
|
|
897
|
+
use the same pattern of trials, by seeding its startpoint.
|
|
898
|
+
|
|
899
|
+
originPath: a string describing the location of the script /
|
|
900
|
+
experiment file path. The psydat file format will store a
|
|
901
|
+
copy of the experiment if possible. If `originPath==None`
|
|
902
|
+
is provided here then the TrialHandler will still store a
|
|
903
|
+
copy of the script where it was
|
|
904
|
+
created. If `OriginPath==-1` then nothing will be stored.
|
|
905
|
+
|
|
906
|
+
:Attributes (after creation):
|
|
907
|
+
|
|
908
|
+
.data - a dictionary of numpy arrays, one for each data type
|
|
909
|
+
stored
|
|
910
|
+
|
|
911
|
+
.trialList - the original list of dicts, specifying the conditions
|
|
912
|
+
|
|
913
|
+
.thisIndex - the index of the current trial in the original
|
|
914
|
+
conditions list
|
|
915
|
+
|
|
916
|
+
.nTotal - the total number of trials that will be run
|
|
917
|
+
|
|
918
|
+
.nRemaining - the total number of trials remaining
|
|
919
|
+
|
|
920
|
+
.thisN - total trials completed so far
|
|
921
|
+
|
|
922
|
+
.thisRepN - which repeat you are currently on
|
|
923
|
+
|
|
924
|
+
.thisTrialN - which trial number *within* that repeat
|
|
925
|
+
|
|
926
|
+
.thisTrial - a dictionary giving the parameters of the current
|
|
927
|
+
trial
|
|
928
|
+
|
|
929
|
+
.finished - True/False for have we finished yet
|
|
930
|
+
|
|
931
|
+
.extraInfo - the dictionary of extra info as given at beginning
|
|
932
|
+
|
|
933
|
+
.origin - the contents of the script or builder experiment that
|
|
934
|
+
created the handler
|
|
935
|
+
|
|
936
|
+
.isTrials - is this controlling trials, or created for another purpose (e.g. iterating a
|
|
937
|
+
stimulus within a trial)?
|
|
938
|
+
|
|
939
|
+
"""
|
|
940
|
+
self.name = name
|
|
941
|
+
self.autoLog = autoLog
|
|
942
|
+
self.isTrials = isTrials
|
|
943
|
+
|
|
944
|
+
if trialList in [None, [None], []]: # user wants an empty trialList
|
|
945
|
+
# which corresponds to a list with a single empty entry
|
|
946
|
+
self.trialList = [None]
|
|
947
|
+
self.columns = []
|
|
948
|
+
# user has hopefully specified a filename
|
|
949
|
+
elif isinstance(trialList, str) and os.path.isfile(trialList):
|
|
950
|
+
# import conditions from that file
|
|
951
|
+
self.trialList, self.columns = importConditions(
|
|
952
|
+
trialList,
|
|
953
|
+
returnFieldNames=True)
|
|
954
|
+
else:
|
|
955
|
+
self.trialList = trialList
|
|
956
|
+
self.columns = list(trialList[0].keys())
|
|
957
|
+
# convert any entry in the TrialList into a TrialType object (with
|
|
958
|
+
# obj.key or obj[key] access)
|
|
959
|
+
for n, entry in enumerate(self.trialList):
|
|
960
|
+
if type(entry) == dict:
|
|
961
|
+
self.trialList[n] = TrialType(entry)
|
|
962
|
+
self.nReps = int(nReps)
|
|
963
|
+
self.nTotal = self.nReps * len(self.trialList)
|
|
964
|
+
self.nRemaining = self.nTotal # subtract 1 each trial
|
|
965
|
+
self.remainingIndices = []
|
|
966
|
+
self.prevIndices = []
|
|
967
|
+
self.method = method
|
|
968
|
+
self.extraInfo = extraInfo
|
|
969
|
+
self.seed = seed
|
|
970
|
+
self._rng = np.random.default_rng(seed=seed)
|
|
971
|
+
self._trialAborted = False
|
|
972
|
+
|
|
973
|
+
# store a list of dicts, convert to pandas DataFrame on access
|
|
974
|
+
self.elapsedTrials = []
|
|
975
|
+
self.upcomingTrials = None
|
|
976
|
+
self.thisTrial = None
|
|
977
|
+
self._cancelNextIteration = False
|
|
978
|
+
|
|
979
|
+
self.originPath, self.origin = self.getOriginPathAndFile(originPath)
|
|
980
|
+
self._exp = None # the experiment handler that owns me!
|
|
981
|
+
|
|
982
|
+
def __iter__(self):
|
|
983
|
+
return self
|
|
984
|
+
|
|
985
|
+
def __repr__(self):
|
|
986
|
+
"""prints a more verbose version of self as string
|
|
987
|
+
"""
|
|
988
|
+
return self.__str__(verbose=True)
|
|
989
|
+
|
|
990
|
+
def __str__(self, verbose=False):
|
|
991
|
+
"""string representation of the object
|
|
992
|
+
"""
|
|
993
|
+
strRepres = 'psychopy.data.{}(\n'.format(self.__class__.__name__)
|
|
994
|
+
attribs = dir(self)
|
|
995
|
+
# data first, then all others
|
|
996
|
+
try:
|
|
997
|
+
data = self.data
|
|
998
|
+
except Exception:
|
|
999
|
+
strRepres += '\t(no data)\n'
|
|
1000
|
+
else:
|
|
1001
|
+
strRepres += str('\tdata=')
|
|
1002
|
+
strRepres += str(data) + '\n'
|
|
1003
|
+
|
|
1004
|
+
method_string = "<class 'method'>"
|
|
1005
|
+
|
|
1006
|
+
for thisAttrib in attribs:
|
|
1007
|
+
# can handle each attribute differently
|
|
1008
|
+
if method_string in str(type(getattr(self, thisAttrib))):
|
|
1009
|
+
# this is a method
|
|
1010
|
+
continue
|
|
1011
|
+
elif thisAttrib[0] == '_':
|
|
1012
|
+
# the attrib is private
|
|
1013
|
+
continue
|
|
1014
|
+
elif thisAttrib == 'data':
|
|
1015
|
+
# we handled this first
|
|
1016
|
+
continue
|
|
1017
|
+
elif (len(str(getattr(self, thisAttrib))) > 20 and
|
|
1018
|
+
not verbose):
|
|
1019
|
+
# just give type of LONG public attribute
|
|
1020
|
+
strRepres += str('\t' + thisAttrib + '=')
|
|
1021
|
+
strRepres += str(type(getattr(self, thisAttrib))) + '\n'
|
|
1022
|
+
else:
|
|
1023
|
+
# give the complete contents of attribute
|
|
1024
|
+
strRepres += str('\t' + thisAttrib + '=')
|
|
1025
|
+
strRepres += str(getattr(self, thisAttrib)) + '\n'
|
|
1026
|
+
strRepres += ')'
|
|
1027
|
+
return strRepres
|
|
1028
|
+
|
|
1029
|
+
def __eq__(self, other):
|
|
1030
|
+
# We want to ignore the RNG object when doing the comparison.
|
|
1031
|
+
self_copy = copy.deepcopy(self)
|
|
1032
|
+
other_copy = copy.deepcopy(other)
|
|
1033
|
+
|
|
1034
|
+
# Only delete _rng if it exists
|
|
1035
|
+
if hasattr(self_copy, '_rng'):
|
|
1036
|
+
del self_copy._rng
|
|
1037
|
+
if hasattr(other_copy, '_rng'):
|
|
1038
|
+
del other_copy._rng
|
|
1039
|
+
|
|
1040
|
+
result = super(TrialHandler2, self_copy).__eq__(other_copy)
|
|
1041
|
+
return result
|
|
1042
|
+
|
|
1043
|
+
@property
|
|
1044
|
+
def data(self):
|
|
1045
|
+
"""Returns a pandas DataFrame of the trial data so far
|
|
1046
|
+
Read only attribute - you can't directly modify TrialHandler.data
|
|
1047
|
+
|
|
1048
|
+
Note that data are stored internally as a list of dictionaries,
|
|
1049
|
+
one per trial. These are converted to a DataFrame on access.
|
|
1050
|
+
"""
|
|
1051
|
+
return pd.DataFrame(self.elapsedTrials)
|
|
1052
|
+
|
|
1053
|
+
def __next__(self):
|
|
1054
|
+
"""Advances to next trial and returns it.
|
|
1055
|
+
Updates attributes; thisTrial, thisTrialN and thisIndex
|
|
1056
|
+
If the trials have ended this method will raise a StopIteration error.
|
|
1057
|
+
This can be handled with code such as::
|
|
1058
|
+
|
|
1059
|
+
trials = data.TrialHandler(.......)
|
|
1060
|
+
for eachTrial in trials: # automatically stops when done
|
|
1061
|
+
# do stuff
|
|
1062
|
+
|
|
1063
|
+
or::
|
|
1064
|
+
|
|
1065
|
+
trials = data.TrialHandler(.......)
|
|
1066
|
+
while True: # ie forever
|
|
1067
|
+
try:
|
|
1068
|
+
thisTrial = trials.next()
|
|
1069
|
+
except StopIteration: # we got a StopIteration error
|
|
1070
|
+
break # break out of the forever loop
|
|
1071
|
+
# do stuff here for the trial
|
|
1072
|
+
"""
|
|
1073
|
+
# if we've just rewound/skipped trials, skip just this time
|
|
1074
|
+
if self._cancelNextIteration:
|
|
1075
|
+
self._cancelNextIteration = False
|
|
1076
|
+
return self.thisTrial
|
|
1077
|
+
# mark previous trial as elapsed
|
|
1078
|
+
if self.thisTrial is not None:
|
|
1079
|
+
self.elapsedTrials.append(self.thisTrial)
|
|
1080
|
+
# if upcoming is None, recaculate
|
|
1081
|
+
if self.upcomingTrials is None:
|
|
1082
|
+
self.calculateUpcoming()
|
|
1083
|
+
# if upcoming is empty, finish
|
|
1084
|
+
if not self.upcomingTrials:
|
|
1085
|
+
self.finished = True
|
|
1086
|
+
self.thisTrial = None
|
|
1087
|
+
self._terminate()
|
|
1088
|
+
raise StopIteration
|
|
1089
|
+
# get first upcoming trial
|
|
1090
|
+
self.thisTrial = self.upcomingTrials.pop(0)
|
|
1091
|
+
|
|
1092
|
+
# update data structure with new info
|
|
1093
|
+
self.addData('thisN', self.thisN)
|
|
1094
|
+
self.addData('thisTrialN', self.thisTrialN)
|
|
1095
|
+
self.addData('thisRepN', self.thisRepN)
|
|
1096
|
+
if self.autoLog:
|
|
1097
|
+
msg = 'New trial (rep=%i, index=%i): %s'
|
|
1098
|
+
vals = (self.thisRepN, self.thisTrialN, self.thisTrial)
|
|
1099
|
+
logging.exp(msg % vals, obj=self.thisTrial)
|
|
1100
|
+
|
|
1101
|
+
# update experiment handler entry
|
|
1102
|
+
exp = self.getExp()
|
|
1103
|
+
if exp is not None:
|
|
1104
|
+
exp.updateEntryFromLoop(self)
|
|
1105
|
+
|
|
1106
|
+
return self.thisTrial
|
|
1107
|
+
|
|
1108
|
+
next = __next__ # allows user to call without a loop `val = trials.next()`
|
|
1109
|
+
|
|
1110
|
+
@property
|
|
1111
|
+
def thisIndex(self):
|
|
1112
|
+
if self.thisTrial is None:
|
|
1113
|
+
if len(self.elapsedTrials):
|
|
1114
|
+
return self.elapsedTrials[-1].thisIndex
|
|
1115
|
+
else:
|
|
1116
|
+
return -1
|
|
1117
|
+
return self.thisTrial.thisIndex
|
|
1118
|
+
|
|
1119
|
+
@property
|
|
1120
|
+
def thisN(self):
|
|
1121
|
+
if self.thisTrial is None:
|
|
1122
|
+
if len(self.elapsedTrials):
|
|
1123
|
+
return self.elapsedTrials[-1].thisN
|
|
1124
|
+
else:
|
|
1125
|
+
return -1
|
|
1126
|
+
return self.thisTrial.thisN
|
|
1127
|
+
|
|
1128
|
+
@property
|
|
1129
|
+
def thisTrialN(self):
|
|
1130
|
+
if self.thisTrial is None:
|
|
1131
|
+
if len(self.elapsedTrials):
|
|
1132
|
+
return self.elapsedTrials[-1].thisTrialN
|
|
1133
|
+
else:
|
|
1134
|
+
return -1
|
|
1135
|
+
return self.thisTrial.thisTrialN
|
|
1136
|
+
|
|
1137
|
+
@property
|
|
1138
|
+
def thisRepN(self):
|
|
1139
|
+
if self.thisTrial is None:
|
|
1140
|
+
if len(self.elapsedTrials):
|
|
1141
|
+
return self.elapsedTrials[-1].thisRepN
|
|
1142
|
+
else:
|
|
1143
|
+
return -1
|
|
1144
|
+
return self.thisTrial.thisRepN
|
|
1145
|
+
|
|
1146
|
+
def calculateUpcoming(self, fromIndex=-1):
|
|
1147
|
+
"""Rebuild the sequence of trial/state info as if running the trials
|
|
1148
|
+
|
|
1149
|
+
Args:
|
|
1150
|
+
fromIndex (int, optional): the point in the sequnce from where to rebuild. Defaults to -1.
|
|
1151
|
+
"""
|
|
1152
|
+
# clear upcoming
|
|
1153
|
+
self.upcomingTrials = []
|
|
1154
|
+
# start off at 0 trial
|
|
1155
|
+
thisTrialN = 0
|
|
1156
|
+
thisN = 0
|
|
1157
|
+
thisRepN = -1
|
|
1158
|
+
# empty array to store indices once taken
|
|
1159
|
+
prevIndices = []
|
|
1160
|
+
# empty array to store remaining indices
|
|
1161
|
+
remainingIndices = []
|
|
1162
|
+
# iterate a while loop until we run out of trials
|
|
1163
|
+
while thisN < (self.nReps * len(self.trialList)):
|
|
1164
|
+
if not remainingIndices:
|
|
1165
|
+
# we've just started, or just starting a new repeat
|
|
1166
|
+
sequence = list(range(len(self.trialList)))
|
|
1167
|
+
if (self.method == 'fullRandom' and
|
|
1168
|
+
thisN < (self.nReps * len(self.trialList))):
|
|
1169
|
+
# we've only just started on a fullRandom sequence
|
|
1170
|
+
sequence *= self.nReps
|
|
1171
|
+
# NB permutation *returns* a shuffled array
|
|
1172
|
+
remainingIndices = list(self._rng.permutation(sequence))
|
|
1173
|
+
elif (self.method in ('sequential', 'random') and
|
|
1174
|
+
thisRepN < self.nReps):
|
|
1175
|
+
thisTrialN = 0
|
|
1176
|
+
thisRepN += 1
|
|
1177
|
+
if self.method == 'random':
|
|
1178
|
+
self._rng.shuffle(sequence) # shuffle (is in-place)
|
|
1179
|
+
remainingIndices = list(sequence)
|
|
1180
|
+
else:
|
|
1181
|
+
# we've finished
|
|
1182
|
+
break
|
|
1183
|
+
|
|
1184
|
+
if thisN < len(self.elapsedTrials):
|
|
1185
|
+
# trial has already happened - get its value
|
|
1186
|
+
thisTrial = self.elapsedTrials[thisN]
|
|
1187
|
+
# remove from remaining
|
|
1188
|
+
remainingIndices.pop(remainingIndices.index(thisTrial.thisIndex))
|
|
1189
|
+
else:
|
|
1190
|
+
# fetch the trial info
|
|
1191
|
+
if len(self.trialList) == 0:
|
|
1192
|
+
thisIndex = 0
|
|
1193
|
+
thisTrial = {}
|
|
1194
|
+
else:
|
|
1195
|
+
thisIndex = remainingIndices.pop(0)
|
|
1196
|
+
# if None then use empty dict
|
|
1197
|
+
thisTrial = self.trialList[thisIndex] or {}
|
|
1198
|
+
thisTrial = copy.copy(thisTrial)
|
|
1199
|
+
# make Trial object
|
|
1200
|
+
thisTrial = Trial(
|
|
1201
|
+
self,
|
|
1202
|
+
thisN=thisN,
|
|
1203
|
+
thisRepN=thisRepN,
|
|
1204
|
+
thisTrialN=thisTrialN,
|
|
1205
|
+
thisIndex=thisIndex,
|
|
1206
|
+
data=thisTrial
|
|
1207
|
+
)
|
|
1208
|
+
# otherwise, append trial
|
|
1209
|
+
self.upcomingTrials.append(thisTrial)
|
|
1210
|
+
# for fullRandom check how many times this has come up before
|
|
1211
|
+
if self.method == 'fullRandom':
|
|
1212
|
+
thisTrial.thisRepN = prevIndices.count(thisTrial.thisIndex)
|
|
1213
|
+
# update prev indices
|
|
1214
|
+
prevIndices.append(thisTrial.thisIndex)
|
|
1215
|
+
# update pointer for next trials
|
|
1216
|
+
thisTrialN += 1 # number of trial this pass
|
|
1217
|
+
thisN += 1 # number of trial in total
|
|
1218
|
+
|
|
1219
|
+
def abortCurrentTrial(self, action='random'):
|
|
1220
|
+
"""Abort the current trial.
|
|
1221
|
+
|
|
1222
|
+
Calling this during an experiment replace this trial. The condition
|
|
1223
|
+
related to the aborted trial will be replaced elsewhere in the session
|
|
1224
|
+
depending on the `method` in use for sampling conditions.
|
|
1225
|
+
|
|
1226
|
+
Parameters
|
|
1227
|
+
----------
|
|
1228
|
+
action : str
|
|
1229
|
+
Action to take with the aborted trial. Can be either of `'random'`,
|
|
1230
|
+
or `'append'`. The default action is `'random'`.
|
|
1231
|
+
|
|
1232
|
+
Notes
|
|
1233
|
+
-----
|
|
1234
|
+
* When using `action='random'`, the RNG state for the trial handler is
|
|
1235
|
+
not used.
|
|
1236
|
+
|
|
1237
|
+
"""
|
|
1238
|
+
# clear this trial so it's not appended to elapsed
|
|
1239
|
+
self.thisTrial = None
|
|
1240
|
+
# clear upcoming trials so they're recalculated on next iteration
|
|
1241
|
+
self.upcomingTrials = None
|
|
1242
|
+
|
|
1243
|
+
@property
|
|
1244
|
+
def finished(self):
|
|
1245
|
+
"""
|
|
1246
|
+
Whether this loop has finished or not. Will be True if there are no upcoming trials and
|
|
1247
|
+
False if there are any. Set `.finished = True` to skip all remaining trials (equivalent to
|
|
1248
|
+
calling `.skipTrials()` with a value larger than the number of trials remaining)
|
|
1249
|
+
|
|
1250
|
+
Returns
|
|
1251
|
+
-------
|
|
1252
|
+
bool
|
|
1253
|
+
True if there are no upcoming trials, False otherwise.
|
|
1254
|
+
"""
|
|
1255
|
+
return not bool(self.upcomingTrials)
|
|
1256
|
+
|
|
1257
|
+
@finished.setter
|
|
1258
|
+
def finished(self, value):
|
|
1259
|
+
# when setting finished to True, skip all remaining trials
|
|
1260
|
+
if value:
|
|
1261
|
+
self.upcomingTrials = []
|
|
1262
|
+
else:
|
|
1263
|
+
self.calculateUpcoming()
|
|
1264
|
+
|
|
1265
|
+
def skipTrials(self, n=1):
|
|
1266
|
+
"""
|
|
1267
|
+
Skip ahead n trials - the trials inbetween will be marked as "skipped". If you try to
|
|
1268
|
+
skip past the last trial, will log a warning and skip *to* the last trial.
|
|
1269
|
+
|
|
1270
|
+
Parameters
|
|
1271
|
+
----------
|
|
1272
|
+
n : int
|
|
1273
|
+
Number of trials to skip ahead
|
|
1274
|
+
"""
|
|
1275
|
+
# if skipping past last trial, print warning and skip to last trial
|
|
1276
|
+
if n > len(self.upcomingTrials):
|
|
1277
|
+
logging.warn(
|
|
1278
|
+
f"Requested skip of {n} trials when only {len(self.elapsedTrials)} trials are upcoming. "
|
|
1279
|
+
f"Skipping to the last upcoming trial."
|
|
1280
|
+
)
|
|
1281
|
+
n = len(self.upcomingTrials)
|
|
1282
|
+
# mark as skipping so routines end
|
|
1283
|
+
self.thisTrial.status = constants.STOPPING
|
|
1284
|
+
# before iterating, add "skipped" to data
|
|
1285
|
+
self.addData("skipped", True)
|
|
1286
|
+
# iterate n times
|
|
1287
|
+
for i in range(n):
|
|
1288
|
+
self.__next__()
|
|
1289
|
+
# before iterating, add "skipped" to data
|
|
1290
|
+
self.addData("skipped", True)
|
|
1291
|
+
# advance row in data file
|
|
1292
|
+
if self.getExp() is not None:
|
|
1293
|
+
self.getExp().nextEntry()
|
|
1294
|
+
# mark as recently skipped so the next iteration (if there is one) is cancelled
|
|
1295
|
+
if n or len(self.upcomingTrials):
|
|
1296
|
+
self._cancelNextIteration = True
|
|
1297
|
+
|
|
1298
|
+
return self.thisTrial
|
|
1299
|
+
|
|
1300
|
+
def rewindTrials(self, n=1):
|
|
1301
|
+
"""
|
|
1302
|
+
Rewind back n trials - previously elapsed trials will return to being upcoming. If you
|
|
1303
|
+
try to rewind before the first trial, will log a warning and rewind *to* the first trial.
|
|
1304
|
+
|
|
1305
|
+
Parameters
|
|
1306
|
+
----------
|
|
1307
|
+
n : int
|
|
1308
|
+
Number of trials to rewind back
|
|
1309
|
+
"""
|
|
1310
|
+
# treat -n as n
|
|
1311
|
+
n = abs(n)
|
|
1312
|
+
# if rewinding past first trial, print warning and rewind to first trial
|
|
1313
|
+
if n > len(self.elapsedTrials):
|
|
1314
|
+
logging.warn(
|
|
1315
|
+
f"Requested rewind of {n} trials when only {len(self.elapsedTrials)} trials have "
|
|
1316
|
+
f"elapsed. Rewinding to before the first trial."
|
|
1317
|
+
)
|
|
1318
|
+
n = len(self.elapsedTrials)
|
|
1319
|
+
# start with no trials
|
|
1320
|
+
if self.thisTrial is None:
|
|
1321
|
+
rewound = []
|
|
1322
|
+
else:
|
|
1323
|
+
rewound = [self.thisTrial]
|
|
1324
|
+
# mark as skipping so routines end
|
|
1325
|
+
self.thisTrial.status = constants.STOPPING
|
|
1326
|
+
# pop the last n values from elapsed trials
|
|
1327
|
+
for i in range(n):
|
|
1328
|
+
rewound = [self.elapsedTrials.pop(-1)] + rewound
|
|
1329
|
+
# clear thisTrial so we progress to the first rewound trial
|
|
1330
|
+
self.thisTrial = None
|
|
1331
|
+
# prepend rewound trials to upcoming array
|
|
1332
|
+
self.upcomingTrials = rewound + self.upcomingTrials
|
|
1333
|
+
# progress so we get the first upcoming trial
|
|
1334
|
+
self.__next__()
|
|
1335
|
+
# mark as recently rewound so the next iteration is cancelled
|
|
1336
|
+
self._cancelNextIteration = True
|
|
1337
|
+
|
|
1338
|
+
return self.thisTrial
|
|
1339
|
+
|
|
1340
|
+
def getCurrentTrial(self):
|
|
1341
|
+
"""
|
|
1342
|
+
Returns the current trial (`.thisTrial`)
|
|
1343
|
+
|
|
1344
|
+
Returns
|
|
1345
|
+
-------
|
|
1346
|
+
Trial
|
|
1347
|
+
The current trial
|
|
1348
|
+
"""
|
|
1349
|
+
return self.thisTrial
|
|
1350
|
+
|
|
1351
|
+
def getAllTrials(self):
|
|
1352
|
+
"""
|
|
1353
|
+
Returns all trials (elapsed, current and upcoming) with an index indicating which trial is
|
|
1354
|
+
the current trial.
|
|
1355
|
+
|
|
1356
|
+
Returns
|
|
1357
|
+
-------
|
|
1358
|
+
list[Trial]
|
|
1359
|
+
List of trials, in order (oldest to newest)
|
|
1360
|
+
int
|
|
1361
|
+
Index of the current trial in this list
|
|
1362
|
+
"""
|
|
1363
|
+
return (self.elapsedTrials or []) + [self.thisTrial] + (self.upcomingTrials or []), len(self.elapsedTrials)
|
|
1364
|
+
|
|
1365
|
+
def getFutureTrial(self, n=1):
|
|
1366
|
+
"""
|
|
1367
|
+
Returns the condition for n trials into the future, without
|
|
1368
|
+
advancing the trials. Returns 'None' if attempting to go beyond
|
|
1369
|
+
the last trial.
|
|
1370
|
+
|
|
1371
|
+
Returns
|
|
1372
|
+
-------
|
|
1373
|
+
Trial or None
|
|
1374
|
+
Trial object for n trials into the future.
|
|
1375
|
+
"""
|
|
1376
|
+
# make sure n is an integer
|
|
1377
|
+
if isinstance(n, str) and n.isnumeric():
|
|
1378
|
+
n = int(n)
|
|
1379
|
+
# return None if requesting beyond last trial
|
|
1380
|
+
if self.upcomingTrials is None or n > len(self.upcomingTrials):
|
|
1381
|
+
return None
|
|
1382
|
+
# return the corresponding trial from upcoming trials array
|
|
1383
|
+
return self.upcomingTrials[n-1]
|
|
1384
|
+
|
|
1385
|
+
def getFutureTrials(self, n=None, start=0):
|
|
1386
|
+
"""
|
|
1387
|
+
Returns Trial objects for a given range in the future. Will start looking at `start` trials
|
|
1388
|
+
in the future and will return n trials from then, so e.g. to get all trials from 2 in the
|
|
1389
|
+
future to 5 in the future you would use `start=2` and `n=3`.
|
|
1390
|
+
|
|
1391
|
+
Parameters
|
|
1392
|
+
----------
|
|
1393
|
+
n : int, optional
|
|
1394
|
+
How many trials into the future to look, by default None. Leave as None to show all
|
|
1395
|
+
future trials
|
|
1396
|
+
start : int, optional
|
|
1397
|
+
How many trials into the future to start looking at, by default 0
|
|
1398
|
+
|
|
1399
|
+
Returns
|
|
1400
|
+
-------
|
|
1401
|
+
list[Trial or None]
|
|
1402
|
+
List of Trial objects n long. Any trials beyond the last trial are None.
|
|
1403
|
+
"""
|
|
1404
|
+
# if there are no future trials, return a blank list
|
|
1405
|
+
if self.upcomingTrials is None:
|
|
1406
|
+
return []
|
|
1407
|
+
# if None, get all future trials
|
|
1408
|
+
if n is None:
|
|
1409
|
+
n = len(self.upcomingTrials) - start
|
|
1410
|
+
# blank list to store trials in
|
|
1411
|
+
trials = []
|
|
1412
|
+
# iterate through n trials
|
|
1413
|
+
for i in range(n):
|
|
1414
|
+
# add each to the list
|
|
1415
|
+
trials.append(
|
|
1416
|
+
self.getFutureTrial(start + i + 1)
|
|
1417
|
+
)
|
|
1418
|
+
|
|
1419
|
+
return trials
|
|
1420
|
+
|
|
1421
|
+
def getEarlierTrial(self, n=-1):
|
|
1422
|
+
"""Returns the condition information from n trials previously.
|
|
1423
|
+
Useful for comparisons in n-back tasks. Returns 'None' if trying
|
|
1424
|
+
to access a trial prior to the first.
|
|
1425
|
+
"""
|
|
1426
|
+
# treat positive offset values as equivalent to negative ones:
|
|
1427
|
+
if n > 0:
|
|
1428
|
+
n = n * -1
|
|
1429
|
+
# return None if requesting before first trial
|
|
1430
|
+
if self.upcomingTrials is None or abs(n) > len(self.upcomingTrials):
|
|
1431
|
+
return None
|
|
1432
|
+
# return the corresponding trial from elapsed trials array
|
|
1433
|
+
return self.elapsedTrials[n]
|
|
1434
|
+
|
|
1435
|
+
def _createOutputArray(self, stimOut, dataOut, delim=None,
|
|
1436
|
+
matrixOnly=False):
|
|
1437
|
+
"""Does the leg-work for saveAsText and saveAsExcel.
|
|
1438
|
+
Combines stimOut with ._parseDataOutput()
|
|
1439
|
+
"""
|
|
1440
|
+
if (stimOut == [] and
|
|
1441
|
+
len(self.trialList) and
|
|
1442
|
+
hasattr(self.trialList[0], 'keys')):
|
|
1443
|
+
stimOut = list(self.trialList[0].keys())
|
|
1444
|
+
# these get added somewhere (by DataHandler?)
|
|
1445
|
+
if 'n' in stimOut:
|
|
1446
|
+
stimOut.remove('n')
|
|
1447
|
+
if 'float' in stimOut:
|
|
1448
|
+
stimOut.remove('float')
|
|
1449
|
+
|
|
1450
|
+
lines = []
|
|
1451
|
+
# parse the dataout section of the output
|
|
1452
|
+
dataOut, dataAnal, dataHead = self._createOutputArrayData(dataOut)
|
|
1453
|
+
if not matrixOnly:
|
|
1454
|
+
thisLine = []
|
|
1455
|
+
lines.append(thisLine)
|
|
1456
|
+
# write a header line
|
|
1457
|
+
for heading in list(stimOut) + dataHead:
|
|
1458
|
+
if heading == 'ran_sum':
|
|
1459
|
+
heading = 'n'
|
|
1460
|
+
elif heading == 'order_raw':
|
|
1461
|
+
heading = 'order'
|
|
1462
|
+
thisLine.append(heading)
|
|
1463
|
+
|
|
1464
|
+
# loop through stimuli, writing data
|
|
1465
|
+
for stimN in range(len(self.elapsedTrials)):
|
|
1466
|
+
thisLine = []
|
|
1467
|
+
lines.append(thisLine)
|
|
1468
|
+
# first the params for this stim (from self.trialList)
|
|
1469
|
+
for heading in stimOut:
|
|
1470
|
+
thisLine.append(self.trialList[stimN][heading])
|
|
1471
|
+
|
|
1472
|
+
# then the data for this stim (from self.data)
|
|
1473
|
+
for thisDataOut in dataOut:
|
|
1474
|
+
# make a string version of the data and then format it
|
|
1475
|
+
tmpData = dataAnal[thisDataOut][stimN]
|
|
1476
|
+
if hasattr(tmpData, 'tolist'): # is a numpy array
|
|
1477
|
+
strVersion = str(tmpData.tolist())
|
|
1478
|
+
# for numeric data replace None with a blank cell
|
|
1479
|
+
if tmpData.dtype.kind not in ['SaUV']:
|
|
1480
|
+
strVersion = strVersion.replace('None', '')
|
|
1481
|
+
elif tmpData in [None, 'None']:
|
|
1482
|
+
strVersion = ''
|
|
1483
|
+
else:
|
|
1484
|
+
strVersion = str(tmpData)
|
|
1485
|
+
|
|
1486
|
+
if strVersion == '()':
|
|
1487
|
+
# 'no data' in masked array should show as "--"
|
|
1488
|
+
strVersion = "--"
|
|
1489
|
+
# handle list of values (e.g. rt_raw )
|
|
1490
|
+
if (len(strVersion) and
|
|
1491
|
+
strVersion[0] in '[(' and
|
|
1492
|
+
strVersion[-1] in '])'):
|
|
1493
|
+
strVersion = strVersion[1:-1] # skip first and last chars
|
|
1494
|
+
# handle lists of lists (e.g. raw of multiple key presses)
|
|
1495
|
+
if (len(strVersion) and
|
|
1496
|
+
strVersion[0] in '[(' and
|
|
1497
|
+
strVersion[-1] in '])'):
|
|
1498
|
+
tup = eval(strVersion) # convert back to a tuple
|
|
1499
|
+
for entry in tup:
|
|
1500
|
+
# contents of each entry is a list or tuple so keep in
|
|
1501
|
+
# quotes to avoid probs with delim
|
|
1502
|
+
thisLine.append(str(entry))
|
|
1503
|
+
else:
|
|
1504
|
+
thisLine.extend(strVersion.split(','))
|
|
1505
|
+
|
|
1506
|
+
# add self.extraInfo
|
|
1507
|
+
if (self.extraInfo != None) and not matrixOnly:
|
|
1508
|
+
lines.append([])
|
|
1509
|
+
# give a single line of space and then a heading
|
|
1510
|
+
lines.append(['extraInfo'])
|
|
1511
|
+
for key, value in list(self.extraInfo.items()):
|
|
1512
|
+
lines.append([key, value])
|
|
1513
|
+
return lines
|
|
1514
|
+
|
|
1515
|
+
def _createOutputArrayData(self, dataOut):
|
|
1516
|
+
"""This just creates the dataOut part of the output matrix.
|
|
1517
|
+
It is called by _createOutputArray() which creates the header
|
|
1518
|
+
line and adds the stimOut columns
|
|
1519
|
+
"""
|
|
1520
|
+
dataHead = [] # will store list of data headers
|
|
1521
|
+
dataAnal = dict([]) # will store data that has been analyzed
|
|
1522
|
+
if type(dataOut) == str:
|
|
1523
|
+
# don't do list convert or we get a list of letters
|
|
1524
|
+
dataOut = [dataOut]
|
|
1525
|
+
elif type(dataOut) != list:
|
|
1526
|
+
dataOut = list(dataOut)
|
|
1527
|
+
|
|
1528
|
+
# expand any 'all' dataTypes to be full list of available dataTypes
|
|
1529
|
+
allDataTypes = list(self.data.keys())
|
|
1530
|
+
# ready to go through standard data types
|
|
1531
|
+
dataOutNew = []
|
|
1532
|
+
for thisDataOut in dataOut:
|
|
1533
|
+
if thisDataOut == 'n':
|
|
1534
|
+
# n is really just the sum of the ran trials
|
|
1535
|
+
dataOutNew.append('ran_sum')
|
|
1536
|
+
continue # no need to do more with this one
|
|
1537
|
+
# then break into dataType and analysis
|
|
1538
|
+
dataType, analType = thisDataOut.rsplit('_', 1)
|
|
1539
|
+
if dataType == 'all':
|
|
1540
|
+
dataOutNew.extend(
|
|
1541
|
+
[key + "_" + analType for key in allDataTypes])
|
|
1542
|
+
if 'order_mean' in dataOutNew:
|
|
1543
|
+
dataOutNew.remove('order_mean')
|
|
1544
|
+
if 'order_std' in dataOutNew:
|
|
1545
|
+
dataOutNew.remove('order_std')
|
|
1546
|
+
else:
|
|
1547
|
+
dataOutNew.append(thisDataOut)
|
|
1548
|
+
dataOut = dataOutNew
|
|
1549
|
+
# sort so all datatypes come together, rather than all analtypes
|
|
1550
|
+
dataOut.sort()
|
|
1551
|
+
|
|
1552
|
+
# do the various analyses, keeping track of fails (e.g. mean of a
|
|
1553
|
+
# string)
|
|
1554
|
+
dataOutInvalid = []
|
|
1555
|
+
# add back special data types (n and order)
|
|
1556
|
+
if 'ran_sum' in dataOut:
|
|
1557
|
+
# move n to the first column
|
|
1558
|
+
dataOut.remove('ran_sum')
|
|
1559
|
+
dataOut.insert(0, 'ran_sum')
|
|
1560
|
+
if 'order_raw' in dataOut:
|
|
1561
|
+
# move order_raw to the second column
|
|
1562
|
+
dataOut.remove('order_raw')
|
|
1563
|
+
dataOut.append('order_raw')
|
|
1564
|
+
# do the necessary analysis on the data
|
|
1565
|
+
for thisDataOutN, thisDataOut in enumerate(dataOut):
|
|
1566
|
+
dataType, analType = thisDataOut.rsplit('_', 1)
|
|
1567
|
+
if not dataType in self.data:
|
|
1568
|
+
# that analysis can't be done
|
|
1569
|
+
dataOutInvalid.append(thisDataOut)
|
|
1570
|
+
continue
|
|
1571
|
+
thisData = self.data[dataType]
|
|
1572
|
+
|
|
1573
|
+
# set the header
|
|
1574
|
+
dataHead.append(dataType + '_' + analType)
|
|
1575
|
+
# analyse thisData using numpy module
|
|
1576
|
+
if analType in dir(np):
|
|
1577
|
+
try:
|
|
1578
|
+
# will fail if we try to take mean of a string for example
|
|
1579
|
+
if analType == 'std':
|
|
1580
|
+
thisAnal = np.std(thisData, axis=1, ddof=0)
|
|
1581
|
+
# normalise by N-1 instead. This should work by
|
|
1582
|
+
# setting ddof=1 but doesn't as of 08/2010 (because
|
|
1583
|
+
# of using a masked array?)
|
|
1584
|
+
N = thisData.shape[1]
|
|
1585
|
+
if N == 1:
|
|
1586
|
+
thisAnal *= 0 # prevent a divide-by-zero error
|
|
1587
|
+
else:
|
|
1588
|
+
sqrt = np.sqrt
|
|
1589
|
+
thisAnal = thisAnal * sqrt(N) / sqrt(N - 1)
|
|
1590
|
+
else:
|
|
1591
|
+
thisAnal = eval("np.%s(thisData,1)" % analType)
|
|
1592
|
+
except Exception:
|
|
1593
|
+
# that analysis doesn't work
|
|
1594
|
+
dataHead.remove(dataType + '_' + analType)
|
|
1595
|
+
dataOutInvalid.append(thisDataOut)
|
|
1596
|
+
continue # to next analysis
|
|
1597
|
+
elif analType == 'raw':
|
|
1598
|
+
thisAnal = thisData
|
|
1599
|
+
else:
|
|
1600
|
+
raise AttributeError('You can only use analyses from numpy')
|
|
1601
|
+
# add extra cols to header if necess
|
|
1602
|
+
if len(thisAnal.shape) > 1:
|
|
1603
|
+
for n in range(thisAnal.shape[1] - 1):
|
|
1604
|
+
dataHead.append("")
|
|
1605
|
+
dataAnal[thisDataOut] = thisAnal
|
|
1606
|
+
|
|
1607
|
+
# remove invalid analyses (e.g. average of a string)
|
|
1608
|
+
for invalidAnal in dataOutInvalid:
|
|
1609
|
+
dataOut.remove(invalidAnal)
|
|
1610
|
+
return dataOut, dataAnal, dataHead
|
|
1611
|
+
|
|
1612
|
+
def saveAsWideText(self, fileName,
|
|
1613
|
+
delim=None,
|
|
1614
|
+
matrixOnly=False,
|
|
1615
|
+
appendFile=True,
|
|
1616
|
+
encoding='utf-8-sig',
|
|
1617
|
+
fileCollisionMethod='rename'):
|
|
1618
|
+
"""Write a text file with the session, stimulus, and data values
|
|
1619
|
+
from each trial in chronological order. Also, return a
|
|
1620
|
+
pandas DataFrame containing same information as the file.
|
|
1621
|
+
|
|
1622
|
+
That is, unlike 'saveAsText' and 'saveAsExcel':
|
|
1623
|
+
- each row comprises information from only a single trial.
|
|
1624
|
+
- no summarising is done (such as collapsing to produce mean and
|
|
1625
|
+
standard deviation values across trials).
|
|
1626
|
+
|
|
1627
|
+
This 'wide' format, as expected by R for creating dataframes, and
|
|
1628
|
+
various other analysis programs, means that some information must
|
|
1629
|
+
be repeated on every row.
|
|
1630
|
+
|
|
1631
|
+
In particular, if the trialHandler's 'extraInfo' exists, then each
|
|
1632
|
+
entry in there occurs in every row. In builder, this will include
|
|
1633
|
+
any entries in the 'Experiment info' field of the
|
|
1634
|
+
'Experiment settings' dialog. In Coder, this information can be set
|
|
1635
|
+
using something like::
|
|
1636
|
+
|
|
1637
|
+
myTrialHandler.extraInfo = {'SubjID': 'Joan Smith',
|
|
1638
|
+
'Group': 'Control'}
|
|
1639
|
+
|
|
1640
|
+
:Parameters:
|
|
1641
|
+
|
|
1642
|
+
fileName:
|
|
1643
|
+
if extension is not specified, '.csv' will be appended if
|
|
1644
|
+
the delimiter is ',', else '.tsv' will be appended.
|
|
1645
|
+
Can include path info.
|
|
1646
|
+
|
|
1647
|
+
delim:
|
|
1648
|
+
allows the user to use a delimiter other than the default
|
|
1649
|
+
tab ("," is popular with file extension ".csv")
|
|
1650
|
+
|
|
1651
|
+
matrixOnly:
|
|
1652
|
+
outputs the data with no header row.
|
|
1653
|
+
|
|
1654
|
+
appendFile:
|
|
1655
|
+
will add this output to the end of the specified file if
|
|
1656
|
+
it already exists.
|
|
1657
|
+
|
|
1658
|
+
fileCollisionMethod:
|
|
1659
|
+
Collision method passed to
|
|
1660
|
+
:func:`~psychopy.tools.fileerrortools.handleFileCollision`
|
|
1661
|
+
|
|
1662
|
+
encoding:
|
|
1663
|
+
The encoding to use when saving a the file.
|
|
1664
|
+
Defaults to `utf-8-sig`.
|
|
1665
|
+
|
|
1666
|
+
"""
|
|
1667
|
+
if self.thisTrialN < 0 and self.thisRepN < 0:
|
|
1668
|
+
# if both are < 1 we haven't started
|
|
1669
|
+
logging.info('TrialHandler.saveAsWideText called but no '
|
|
1670
|
+
'trials completed. Nothing saved')
|
|
1671
|
+
return -1
|
|
1672
|
+
|
|
1673
|
+
# set default delimiter if none given
|
|
1674
|
+
if delim is None:
|
|
1675
|
+
delim = genDelimiter(fileName)
|
|
1676
|
+
|
|
1677
|
+
# create the file or send to stdout
|
|
1678
|
+
fileName = genFilenameFromDelimiter(fileName, delim)
|
|
1679
|
+
|
|
1680
|
+
with openOutputFile(fileName=fileName, append=appendFile,
|
|
1681
|
+
fileCollisionMethod=fileCollisionMethod,
|
|
1682
|
+
encoding=encoding) as f:
|
|
1683
|
+
csvData = self.data.to_csv(sep=delim,
|
|
1684
|
+
encoding=encoding,
|
|
1685
|
+
columns=self.columns, # sets the order
|
|
1686
|
+
header=(not matrixOnly),
|
|
1687
|
+
index=False)
|
|
1688
|
+
f.write(csvData)
|
|
1689
|
+
|
|
1690
|
+
if (fileName is not None) and (fileName != 'stdout'):
|
|
1691
|
+
logging.info('saved wide-format data to %s' % f.name)
|
|
1692
|
+
|
|
1693
|
+
def saveAsJson(self,
|
|
1694
|
+
fileName=None,
|
|
1695
|
+
encoding='utf-8',
|
|
1696
|
+
fileCollisionMethod='rename'):
|
|
1697
|
+
"""
|
|
1698
|
+
Serialize the object to the JSON format.
|
|
1699
|
+
|
|
1700
|
+
Parameters
|
|
1701
|
+
----------
|
|
1702
|
+
fileName: string, or None
|
|
1703
|
+
the name of the file to create or append. Can include a relative or
|
|
1704
|
+
absolute path. If `None`, will not write to a file, but return an
|
|
1705
|
+
in-memory JSON object.
|
|
1706
|
+
|
|
1707
|
+
encoding : string, optional
|
|
1708
|
+
The encoding to use when writing the file.
|
|
1709
|
+
|
|
1710
|
+
fileCollisionMethod : string
|
|
1711
|
+
Collision method passed to
|
|
1712
|
+
:func:`~psychopy.tools.fileerrortools.handleFileCollision`. Can be
|
|
1713
|
+
either of `'rename'`, `'overwrite'`, or `'fail'`.
|
|
1714
|
+
|
|
1715
|
+
Notes
|
|
1716
|
+
-----
|
|
1717
|
+
Currently, a copy of the object is created, and the copy's .origin
|
|
1718
|
+
attribute is set to an empty string before serializing
|
|
1719
|
+
because loading the created JSON file would sometimes fail otherwise.
|
|
1720
|
+
|
|
1721
|
+
The RNG self._rng cannot be serialized as-is, so we store its state in
|
|
1722
|
+
self._rng_state so we can restore it when loading.
|
|
1723
|
+
|
|
1724
|
+
"""
|
|
1725
|
+
self_copy = copy.deepcopy(self)
|
|
1726
|
+
self_copy._rng_state = self_copy._rng.bit_generator.state
|
|
1727
|
+
del self_copy._rng
|
|
1728
|
+
|
|
1729
|
+
r = (super(TrialHandler2, self_copy)
|
|
1730
|
+
.saveAsJson(fileName=fileName,
|
|
1731
|
+
encoding=encoding,
|
|
1732
|
+
fileCollisionMethod=fileCollisionMethod))
|
|
1733
|
+
|
|
1734
|
+
if fileName is None:
|
|
1735
|
+
return r
|
|
1736
|
+
|
|
1737
|
+
def addData(self, thisType, value):
|
|
1738
|
+
"""Add a piece of data to the current trial
|
|
1739
|
+
"""
|
|
1740
|
+
# store in the columns list to help ordering later
|
|
1741
|
+
if thisType not in self.columns:
|
|
1742
|
+
self.columns.append(thisType)
|
|
1743
|
+
# make sure we have a thisTrial
|
|
1744
|
+
if self.thisTrial is None:
|
|
1745
|
+
if self.upcomingTrials:
|
|
1746
|
+
self.thisTrial = self.upcomingTrials.pop(0)
|
|
1747
|
+
else:
|
|
1748
|
+
self.thisTrial = Trial(
|
|
1749
|
+
self,
|
|
1750
|
+
thisN=0,
|
|
1751
|
+
thisRepN=0,
|
|
1752
|
+
thisTrialN=0,
|
|
1753
|
+
thisIndex=0,
|
|
1754
|
+
data={}
|
|
1755
|
+
)
|
|
1756
|
+
# save the actual value in a data dict
|
|
1757
|
+
self.thisTrial[thisType] = value
|
|
1758
|
+
if self.getExp() is not None:
|
|
1759
|
+
# update the experiment handler too
|
|
1760
|
+
self.getExp().addData(f"{self.name}.{thisType}", value)
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
class TrialHandlerExt(TrialHandler):
|
|
1764
|
+
"""A class for handling trial sequences in a *non-counterbalanced design*
|
|
1765
|
+
(i.e. *oddball paradigms*). Its functions are a superset of the
|
|
1766
|
+
class TrialHandler, and as such, can also be used for normal trial
|
|
1767
|
+
handling.
|
|
1768
|
+
|
|
1769
|
+
TrialHandlerExt has the same function names for data storage facilities.
|
|
1770
|
+
|
|
1771
|
+
To use non-counterbalanced designs, all TrialType dict entries in the
|
|
1772
|
+
trial list must have a key called "weight". For example, if you want
|
|
1773
|
+
trial types A, B, C, and D to have 10, 5, 3, and 2 repetitions per
|
|
1774
|
+
block, then the trialList can look like:
|
|
1775
|
+
|
|
1776
|
+
[{Name:'A', ..., weight:10},
|
|
1777
|
+
{Name:'B', ..., weight:5},
|
|
1778
|
+
{Name:'C', ..., weight:3},
|
|
1779
|
+
{Name:'D', ..., weight:2}]
|
|
1780
|
+
|
|
1781
|
+
For experimenters using an excel or csv file for trial list, a column
|
|
1782
|
+
called weight is appropriate for this purpose.
|
|
1783
|
+
|
|
1784
|
+
Calls to .next() will fetch the next trial object given to this handler,
|
|
1785
|
+
according to the method specified (random, sequential, fullRandom).
|
|
1786
|
+
Calls will raise a StopIteration error when all trials are exhausted.
|
|
1787
|
+
|
|
1788
|
+
*Authored by Suddha Sourav at BPN, Uni Hamburg - heavily borrowing
|
|
1789
|
+
from the TrialHandler class*
|
|
1790
|
+
"""
|
|
1791
|
+
|
|
1792
|
+
def __init__(self,
|
|
1793
|
+
trialList,
|
|
1794
|
+
nReps,
|
|
1795
|
+
method='random',
|
|
1796
|
+
dataTypes=None,
|
|
1797
|
+
extraInfo=None,
|
|
1798
|
+
seed=None,
|
|
1799
|
+
originPath=None,
|
|
1800
|
+
name='',
|
|
1801
|
+
autoLog=True):
|
|
1802
|
+
"""
|
|
1803
|
+
|
|
1804
|
+
:Parameters:
|
|
1805
|
+
|
|
1806
|
+
trialList: a simple list (or flat array) of dictionaries
|
|
1807
|
+
specifying conditions. This can be imported from an
|
|
1808
|
+
excel / csv file using :func:`~psychopy.data.importConditions`
|
|
1809
|
+
For non-counterbalanced designs, each dict entry in
|
|
1810
|
+
trialList must have a key called weight!
|
|
1811
|
+
|
|
1812
|
+
nReps: number of repeats for all conditions. When using a
|
|
1813
|
+
non-counterbalanced design, nReps is analogous to the number
|
|
1814
|
+
of blocks.
|
|
1815
|
+
|
|
1816
|
+
method: *'random',* 'sequential', or 'fullRandom'
|
|
1817
|
+
When the weights are not specified:
|
|
1818
|
+
'sequential' presents the conditions in the order they appear
|
|
1819
|
+
in the list. 'random' will result in a shuffle of the
|
|
1820
|
+
conditions on each repeat, but all conditions occur once
|
|
1821
|
+
before the second repeat etc. 'fullRandom' fully randomises
|
|
1822
|
+
the trials across repeats as well, which means you could
|
|
1823
|
+
potentially run all trials of one condition before any trial
|
|
1824
|
+
of another.
|
|
1825
|
+
|
|
1826
|
+
In the presence of weights:
|
|
1827
|
+
'sequential' presents each trial type the number of times
|
|
1828
|
+
specified by its weight, before moving on to the next type.
|
|
1829
|
+
'random' randomizes the presentation order within block.
|
|
1830
|
+
'fulLRandom' shuffles trial order across weights an nRep,
|
|
1831
|
+
that is, a full shuffling.
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
dataTypes: (optional) list of names for data storage. e.g.
|
|
1835
|
+
['corr','rt','resp']. If not provided then these will be
|
|
1836
|
+
created as needed during calls to
|
|
1837
|
+
:func:`~psychopy.data.TrialHandler.addData`
|
|
1838
|
+
|
|
1839
|
+
extraInfo: A dictionary
|
|
1840
|
+
This will be stored alongside the data and usually describes
|
|
1841
|
+
the experiment and subject ID, date etc.
|
|
1842
|
+
|
|
1843
|
+
seed: an integer
|
|
1844
|
+
If provided then this fixes the random number generator
|
|
1845
|
+
to use the same pattern
|
|
1846
|
+
of trials, by seeding its startpoint
|
|
1847
|
+
|
|
1848
|
+
originPath: a string describing the location of the script /
|
|
1849
|
+
experiment file path. The psydat file format will store a
|
|
1850
|
+
copy of the experiment if possible. If `originPath==None`
|
|
1851
|
+
is provided here then the TrialHandler will still store a
|
|
1852
|
+
copy of the script where it was created. If `OriginPath==-1`
|
|
1853
|
+
then nothing will be stored.
|
|
1854
|
+
|
|
1855
|
+
:Attributes (after creation):
|
|
1856
|
+
|
|
1857
|
+
.data - a dictionary of numpy arrays, one for each data type
|
|
1858
|
+
stored
|
|
1859
|
+
|
|
1860
|
+
.trialList - the original list of dicts, specifying the conditions
|
|
1861
|
+
|
|
1862
|
+
.thisIndex - the index of the current trial in the original
|
|
1863
|
+
conditions list
|
|
1864
|
+
|
|
1865
|
+
.nTotal - the total number of trials that will be run
|
|
1866
|
+
|
|
1867
|
+
.nRemaining - the total number of trials remaining
|
|
1868
|
+
|
|
1869
|
+
.thisN - total trials completed so far
|
|
1870
|
+
|
|
1871
|
+
.thisRepN - which repeat you are currently on
|
|
1872
|
+
|
|
1873
|
+
.thisTrialN - which trial number *within* that repeat
|
|
1874
|
+
|
|
1875
|
+
.thisTrial - a dictionary giving the parameters of the current
|
|
1876
|
+
trial
|
|
1877
|
+
|
|
1878
|
+
.finished - True/False for have we finished yet
|
|
1879
|
+
|
|
1880
|
+
.extraInfo - the dictionary of extra info as given at beginning
|
|
1881
|
+
|
|
1882
|
+
.origin - the contents of the script or builder experiment that
|
|
1883
|
+
created the handler
|
|
1884
|
+
|
|
1885
|
+
.trialWeights - None if all weights are not specified. If all
|
|
1886
|
+
weights are specified, then a list containing the weights
|
|
1887
|
+
of the trial types.
|
|
1888
|
+
|
|
1889
|
+
"""
|
|
1890
|
+
self.name = name
|
|
1891
|
+
self.autoLog = autoLog
|
|
1892
|
+
|
|
1893
|
+
if trialList in (None, []):
|
|
1894
|
+
# user wants an empty trialList
|
|
1895
|
+
# which corresponds to a list with a single empty entry
|
|
1896
|
+
self.trialList = [None]
|
|
1897
|
+
# user has hopefully specified a filename
|
|
1898
|
+
elif isinstance(trialList, str) and os.path.isfile(trialList):
|
|
1899
|
+
# import conditions from that file
|
|
1900
|
+
self.trialList = importConditions(trialList)
|
|
1901
|
+
else:
|
|
1902
|
+
self.trialList = trialList
|
|
1903
|
+
# convert any entry in the TrialList into a TrialType object (with
|
|
1904
|
+
# obj.key or obj[key] access)
|
|
1905
|
+
for n, entry in enumerate(self.trialList):
|
|
1906
|
+
if type(entry) == dict:
|
|
1907
|
+
self.trialList[n] = TrialType(entry)
|
|
1908
|
+
self.nReps = nReps
|
|
1909
|
+
# Add Su
|
|
1910
|
+
if not trialList or not all('weight' in d for d in trialList):
|
|
1911
|
+
self.trialWeights = None
|
|
1912
|
+
self.nTotal = self.nReps * len(self.trialList)
|
|
1913
|
+
else:
|
|
1914
|
+
self.trialWeights = [d['weight'] for d in trialList]
|
|
1915
|
+
self.nTotal = self.nReps * sum(self.trialWeights)
|
|
1916
|
+
self.nRemaining = self.nTotal # subtract 1 each trial
|
|
1917
|
+
self.method = method
|
|
1918
|
+
self.thisRepN = 0 # records which repetition or pass we are on
|
|
1919
|
+
self.thisTrialN = -1 # records trial number within this repetition
|
|
1920
|
+
self.thisN = -1
|
|
1921
|
+
self.thisIndex = 0 # index of current trial in the conditions list
|
|
1922
|
+
self.thisTrial = []
|
|
1923
|
+
self.finished = False
|
|
1924
|
+
self.extraInfo = extraInfo
|
|
1925
|
+
self.seed = seed
|
|
1926
|
+
# create dataHandler
|
|
1927
|
+
if self.trialWeights is None:
|
|
1928
|
+
self.data = DataHandler(trials=self)
|
|
1929
|
+
else:
|
|
1930
|
+
self.data = DataHandler(trials=self,
|
|
1931
|
+
dataShape=[sum(self.trialWeights), nReps])
|
|
1932
|
+
if dataTypes is not None:
|
|
1933
|
+
self.data.addDataType(dataTypes)
|
|
1934
|
+
self.data.addDataType('ran')
|
|
1935
|
+
self.data['ran'].mask = False # bool - all entries are valid
|
|
1936
|
+
self.data.addDataType('order')
|
|
1937
|
+
# generate stimulus sequence
|
|
1938
|
+
if self.method in ('random', 'sequential', 'fullRandom'):
|
|
1939
|
+
self.sequenceIndices = self._createSequence()
|
|
1940
|
+
else:
|
|
1941
|
+
self.sequenceIndices = []
|
|
1942
|
+
|
|
1943
|
+
self.originPath, self.origin = self.getOriginPathAndFile(originPath)
|
|
1944
|
+
self._exp = None # the experiment handler that owns me!
|
|
1945
|
+
|
|
1946
|
+
def _createSequence(self):
|
|
1947
|
+
"""Pre-generates the sequence of trial presentations (for
|
|
1948
|
+
non-adaptive methods). This is called automatically when the
|
|
1949
|
+
TrialHandler is initialised so doesn't need an explicit call
|
|
1950
|
+
from the user.
|
|
1951
|
+
|
|
1952
|
+
The returned sequence has form indices[stimN][repN]
|
|
1953
|
+
Example: sequential with 6 trialtypes (rows), 5 reps (cols), returns::
|
|
1954
|
+
|
|
1955
|
+
[[0 0 0 0 0]
|
|
1956
|
+
[1 1 1 1 1]
|
|
1957
|
+
[2 2 2 2 2]
|
|
1958
|
+
[3 3 3 3 3]
|
|
1959
|
+
[4 4 4 4 4]
|
|
1960
|
+
[5 5 5 5 5]]
|
|
1961
|
+
|
|
1962
|
+
These 30 trials will be returned by .next() in the order:
|
|
1963
|
+
0, 1, 2, 3, 4, 5, 0, 1, 2, ... ... 3, 4, 5
|
|
1964
|
+
|
|
1965
|
+
Example: random, with 3 trialtypes, where the weights of
|
|
1966
|
+
conditions 0,1, and 2 are 3,2, and 1 respectively,
|
|
1967
|
+
and a rep value of 5, might return::
|
|
1968
|
+
|
|
1969
|
+
[[0 1 2 0 1]
|
|
1970
|
+
[1 0 1 1 1]
|
|
1971
|
+
[0 2 0 0 0]
|
|
1972
|
+
[0 0 0 1 0]
|
|
1973
|
+
[2 0 1 0 2]
|
|
1974
|
+
[1 1 0 2 0]]
|
|
1975
|
+
|
|
1976
|
+
These 30 trials will be returned by .next() in the order:
|
|
1977
|
+
0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 1, ...
|
|
1978
|
+
... 0, 2, 0 *stopIteration*
|
|
1979
|
+
|
|
1980
|
+
To add a new type of sequence (as of v1.65.02):
|
|
1981
|
+
- add the sequence generation code here
|
|
1982
|
+
- adjust "if self.method in [ ...]:" in both __init__ and .next()
|
|
1983
|
+
- adjust allowedVals in experiment.py -> shows up in DlgLoopProperties
|
|
1984
|
+
Note that users can make any sequence whatsoever outside of PsychoPy,
|
|
1985
|
+
and specify sequential order; any order is possible this way.
|
|
1986
|
+
"""
|
|
1987
|
+
# create indices for a single rep
|
|
1988
|
+
indices = np.asarray(self._makeIndices(self.trialList), dtype=int)
|
|
1989
|
+
|
|
1990
|
+
repeat = np.repeat
|
|
1991
|
+
reshape = np.reshape
|
|
1992
|
+
rng = np.random.default_rng(seed=self.seed)
|
|
1993
|
+
if self.method == 'random':
|
|
1994
|
+
seqIndices = []
|
|
1995
|
+
if self.trialWeights is None:
|
|
1996
|
+
thisRepSeq = indices.flat # take a fresh copy
|
|
1997
|
+
else:
|
|
1998
|
+
thisRepSeq = repeat(indices, self.trialWeights)
|
|
1999
|
+
for thisRep in range(self.nReps):
|
|
2000
|
+
seqIndices.append(rng.permutation(thisRepSeq))
|
|
2001
|
+
seqIndices = np.transpose(seqIndices)
|
|
2002
|
+
elif self.method == 'sequential':
|
|
2003
|
+
if self.trialWeights is None:
|
|
2004
|
+
seqIndices = repeat(indices, self.nReps, 1)
|
|
2005
|
+
else:
|
|
2006
|
+
_base = repeat(indices, self.trialWeights, 0)
|
|
2007
|
+
seqIndices = repeat(_base, self.nReps, 1)
|
|
2008
|
+
elif self.method == 'fullRandom':
|
|
2009
|
+
if self.trialWeights is None:
|
|
2010
|
+
# indices * nReps, flatten, shuffle, unflatten;
|
|
2011
|
+
# only use seed once
|
|
2012
|
+
sequential = np.repeat(indices, self.nReps, 1) # = sequential
|
|
2013
|
+
randomFlat = rng.permutation(sequential.flat)
|
|
2014
|
+
seqIndices = np.reshape(
|
|
2015
|
+
randomFlat, (len(indices), self.nReps))
|
|
2016
|
+
else:
|
|
2017
|
+
_base = repeat(indices, self.trialWeights, 0)
|
|
2018
|
+
sequential = repeat(_base, self.nReps, 1)
|
|
2019
|
+
randomFlat = rng.permutation(sequential.flat)
|
|
2020
|
+
seqIndices = reshape(randomFlat,
|
|
2021
|
+
(sum(self.trialWeights), self.nReps))
|
|
2022
|
+
|
|
2023
|
+
if self.autoLog:
|
|
2024
|
+
# Change
|
|
2025
|
+
msg = 'Created sequence: %s, trialTypes=%d, nReps=%d, seed=%s'
|
|
2026
|
+
vals = (self.method, len(indices), self.nReps, str(self.seed))
|
|
2027
|
+
logging.exp(msg % vals)
|
|
2028
|
+
return seqIndices
|
|
2029
|
+
|
|
2030
|
+
def __next__(self):
|
|
2031
|
+
"""Advances to next trial and returns it.
|
|
2032
|
+
Updates attributes; thisTrial, thisTrialN and thisIndex
|
|
2033
|
+
If the trials have ended this method will raise a StopIteration error.
|
|
2034
|
+
This can be handled with code such as::
|
|
2035
|
+
|
|
2036
|
+
trials = data.TrialHandler(.......)
|
|
2037
|
+
for eachTrial in trials: # automatically stops when done
|
|
2038
|
+
# do stuff
|
|
2039
|
+
|
|
2040
|
+
or::
|
|
2041
|
+
|
|
2042
|
+
trials = data.TrialHandler(.......)
|
|
2043
|
+
while True: # ie forever
|
|
2044
|
+
try:
|
|
2045
|
+
thisTrial = trials.next()
|
|
2046
|
+
except StopIteration: # we got a StopIteration error
|
|
2047
|
+
break # break out of the forever loop
|
|
2048
|
+
# do stuff here for the trial
|
|
2049
|
+
"""
|
|
2050
|
+
# update pointer for next trials
|
|
2051
|
+
self.thisTrialN += 1 # number of trial this pass
|
|
2052
|
+
self.thisN += 1 # number of trial in total
|
|
2053
|
+
self.nRemaining -= 1
|
|
2054
|
+
|
|
2055
|
+
if self.trialWeights is None:
|
|
2056
|
+
if self.thisTrialN == len(self.trialList):
|
|
2057
|
+
# start a new repetition
|
|
2058
|
+
self.thisTrialN = 0
|
|
2059
|
+
self.thisRepN += 1
|
|
2060
|
+
else:
|
|
2061
|
+
if self.thisTrialN == sum(self.trialWeights):
|
|
2062
|
+
# start a new repetition
|
|
2063
|
+
self.thisTrialN = 0
|
|
2064
|
+
self.thisRepN += 1
|
|
2065
|
+
|
|
2066
|
+
if self.thisRepN >= self.nReps:
|
|
2067
|
+
# all reps complete
|
|
2068
|
+
self.thisTrial = []
|
|
2069
|
+
self.finished = True
|
|
2070
|
+
|
|
2071
|
+
if self.finished == True:
|
|
2072
|
+
self._terminate()
|
|
2073
|
+
|
|
2074
|
+
# fetch the trial info
|
|
2075
|
+
if self.method in ('random', 'sequential', 'fullRandom'):
|
|
2076
|
+
if self.trialWeights is None:
|
|
2077
|
+
idx = self.sequenceIndices[self.thisTrialN]
|
|
2078
|
+
self.thisIndex = idx[self.thisRepN]
|
|
2079
|
+
self.thisTrial = self.trialList[self.thisIndex]
|
|
2080
|
+
self.data.add('ran', 1)
|
|
2081
|
+
self.data.add('order', self.thisN)
|
|
2082
|
+
else:
|
|
2083
|
+
idx = self.sequenceIndices[self.thisTrialN]
|
|
2084
|
+
self.thisIndex = idx[self.thisRepN]
|
|
2085
|
+
self.thisTrial = self.trialList[self.thisIndex]
|
|
2086
|
+
|
|
2087
|
+
self.data.add('ran', 1,
|
|
2088
|
+
position=self.getNextTrialPosInDataHandler())
|
|
2089
|
+
# The last call already adds a ran to this trial, so get the
|
|
2090
|
+
# current pos now
|
|
2091
|
+
self.data.add('order', self.thisN,
|
|
2092
|
+
position=self.getCurrentTrialPosInDataHandler())
|
|
2093
|
+
|
|
2094
|
+
if self.autoLog:
|
|
2095
|
+
msg = 'New trial (rep=%i, index=%i): %s'
|
|
2096
|
+
vals = (self.thisRepN, self.thisTrialN, self.thisTrial)
|
|
2097
|
+
logging.exp(msg % vals, obj=self.thisTrial)
|
|
2098
|
+
return self.thisTrial
|
|
2099
|
+
|
|
2100
|
+
next = __next__ # allows user to call without a loop `val = trials.next()`
|
|
2101
|
+
|
|
2102
|
+
def getCurrentTrialPosInDataHandler(self):
|
|
2103
|
+
# if there's no trial weights, then the current position is simply
|
|
2104
|
+
# [trialIndex, nRepetition]
|
|
2105
|
+
if self.trialWeights is None:
|
|
2106
|
+
repN = sum(self['ran'][self.trials.thisIndex]) - 1
|
|
2107
|
+
position = [self.trials.thisIndex, repN]
|
|
2108
|
+
else:
|
|
2109
|
+
# if there are trial weights, the situation is slightly more
|
|
2110
|
+
# involved, because the same index can be repeated for a number
|
|
2111
|
+
# of times. If we had a sequential array, then the rows in
|
|
2112
|
+
# DataHandler for that trialIndex would be from
|
|
2113
|
+
# sum(trialWeights[begin:trialIndex]) to
|
|
2114
|
+
# sum(trialWeights[begin:trialIndex+1]).
|
|
2115
|
+
|
|
2116
|
+
# if we haven't begun the experiment yet, then the last row
|
|
2117
|
+
# of the first column is used as the current position,
|
|
2118
|
+
# emulating what TrialHandler does. The following two lines
|
|
2119
|
+
# also prevents calculating garbage position values in case
|
|
2120
|
+
# the first row has a null weight
|
|
2121
|
+
if self.thisN < 0:
|
|
2122
|
+
return [0, -1]
|
|
2123
|
+
|
|
2124
|
+
firstRowIndex = sum(self.trialWeights[:self.thisIndex])
|
|
2125
|
+
lastRowIndex = sum(self.trialWeights[:self.thisIndex + 1])
|
|
2126
|
+
|
|
2127
|
+
# get the number of the trial presented by summing in ran for the
|
|
2128
|
+
# rows above and all columns
|
|
2129
|
+
# BF-Sourav-29032021: numpy returns float, so cast to int
|
|
2130
|
+
nThisTrialPresented = int(round(np.sum(
|
|
2131
|
+
self.data['ran'][firstRowIndex:lastRowIndex, :])))
|
|
2132
|
+
|
|
2133
|
+
_tw = self.trialWeights[self.thisIndex]
|
|
2134
|
+
dataRowThisTrial = firstRowIndex + (nThisTrialPresented - 1) % _tw
|
|
2135
|
+
dataColThisTrial = int((nThisTrialPresented - 1) // _tw)
|
|
2136
|
+
|
|
2137
|
+
position = [dataRowThisTrial, dataColThisTrial]
|
|
2138
|
+
|
|
2139
|
+
return position
|
|
2140
|
+
|
|
2141
|
+
def getNextTrialPosInDataHandler(self):
|
|
2142
|
+
# if there's no trial weights, then the current position is
|
|
2143
|
+
# simply [trialIndex, nRepetition]
|
|
2144
|
+
if self.trialWeights is None:
|
|
2145
|
+
repN = sum(self['ran'][self.trials.thisIndex])
|
|
2146
|
+
position = [self.trials.thisIndex, repN]
|
|
2147
|
+
else:
|
|
2148
|
+
# if there are trial weights, the situation is slightly more
|
|
2149
|
+
# involved, because the same index can be repeated for a
|
|
2150
|
+
# number of times. If we had a sequential array, then the
|
|
2151
|
+
# rows in DataHandler for that trialIndex would
|
|
2152
|
+
# be from sum(trialWeights[begin:trialIndex]) to
|
|
2153
|
+
# sum(trialWeights[begin:trialIndex+1]).
|
|
2154
|
+
|
|
2155
|
+
firstRowIndex = sum(self.trialWeights[:self.thisIndex])
|
|
2156
|
+
lastRowIndex = sum(self.trialWeights[:self.thisIndex + 1])
|
|
2157
|
+
|
|
2158
|
+
# get the number of the trial presented by summing in ran for the
|
|
2159
|
+
# rows above and all columns
|
|
2160
|
+
# BF-Sourav-29032021: numpy returns float, so cast to int
|
|
2161
|
+
nThisTrialPresented = int(round(np.sum(
|
|
2162
|
+
self.data['ran'][firstRowIndex:lastRowIndex, :])))
|
|
2163
|
+
|
|
2164
|
+
_tw = self.trialWeights[self.thisIndex]
|
|
2165
|
+
dataRowThisTrial = firstRowIndex + nThisTrialPresented % _tw
|
|
2166
|
+
dataColThisTrial = int(nThisTrialPresented // _tw)
|
|
2167
|
+
|
|
2168
|
+
position = [dataRowThisTrial, dataColThisTrial]
|
|
2169
|
+
|
|
2170
|
+
return position
|
|
2171
|
+
|
|
2172
|
+
def addData(self, thisType, value, position=None):
|
|
2173
|
+
"""Add data for the current trial
|
|
2174
|
+
"""
|
|
2175
|
+
|
|
2176
|
+
if self.trialWeights is None:
|
|
2177
|
+
pos = None
|
|
2178
|
+
else:
|
|
2179
|
+
pos = self.getCurrentTrialPosInDataHandler()
|
|
2180
|
+
self.data.add(thisType, value, position=pos)
|
|
2181
|
+
# change this!
|
|
2182
|
+
if self.getExp() is not None:
|
|
2183
|
+
# update the experiment handler too:
|
|
2184
|
+
self.getExp().addData(thisType, value)
|
|
2185
|
+
|
|
2186
|
+
def _createOutputArrayData(self, dataOut):
|
|
2187
|
+
"""This just creates the dataOut part of the output matrix.
|
|
2188
|
+
It is called by _createOutputArray() which creates the header
|
|
2189
|
+
line and adds the stimOut columns
|
|
2190
|
+
"""
|
|
2191
|
+
|
|
2192
|
+
if self.trialWeights is not None:
|
|
2193
|
+
# remember to use other array instead of self.data
|
|
2194
|
+
_vals = np.arange(len(self.trialList))
|
|
2195
|
+
idx_data = np.repeat(_vals, self.trialWeights)
|
|
2196
|
+
|
|
2197
|
+
# list of data headers
|
|
2198
|
+
dataHead = []
|
|
2199
|
+
# will store data that has been analyzed
|
|
2200
|
+
dataAnal = dict([])
|
|
2201
|
+
if type(dataOut) == str:
|
|
2202
|
+
# don't do list convert or we get a list of letters
|
|
2203
|
+
dataOut = [dataOut]
|
|
2204
|
+
elif type(dataOut) != list:
|
|
2205
|
+
dataOut = list(dataOut)
|
|
2206
|
+
|
|
2207
|
+
# expand any 'all' dataTypes to the full list of available dataTypes
|
|
2208
|
+
allDataTypes = list(self.data.keys())
|
|
2209
|
+
# treat these separately later
|
|
2210
|
+
allDataTypes.remove('ran')
|
|
2211
|
+
# ready to go through standard data types
|
|
2212
|
+
dataOutNew = []
|
|
2213
|
+
for thisDataOut in dataOut:
|
|
2214
|
+
if thisDataOut == 'n':
|
|
2215
|
+
# n is really just the sum of the ran trials
|
|
2216
|
+
dataOutNew.append('ran_sum')
|
|
2217
|
+
continue # no need to do more with this one
|
|
2218
|
+
# then break into dataType and analysis
|
|
2219
|
+
dataType, analType = thisDataOut.rsplit('_', 1)
|
|
2220
|
+
if dataType == 'all':
|
|
2221
|
+
keyType = [key + "_" + analType for key in allDataTypes]
|
|
2222
|
+
dataOutNew.extend(keyType)
|
|
2223
|
+
if 'order_mean' in dataOutNew:
|
|
2224
|
+
dataOutNew.remove('order_mean')
|
|
2225
|
+
if 'order_std' in dataOutNew:
|
|
2226
|
+
dataOutNew.remove('order_std')
|
|
2227
|
+
else:
|
|
2228
|
+
dataOutNew.append(thisDataOut)
|
|
2229
|
+
dataOut = dataOutNew
|
|
2230
|
+
# sort so that all datatypes come together, rather than all analtypes
|
|
2231
|
+
dataOut.sort()
|
|
2232
|
+
|
|
2233
|
+
# do the various analyses, keeping track of fails (e.g. mean of a
|
|
2234
|
+
# string)
|
|
2235
|
+
dataOutInvalid = []
|
|
2236
|
+
# add back special data types (n and order)
|
|
2237
|
+
if 'ran_sum' in dataOut:
|
|
2238
|
+
# move n to the first column
|
|
2239
|
+
dataOut.remove('ran_sum')
|
|
2240
|
+
dataOut.insert(0, 'ran_sum')
|
|
2241
|
+
if 'order_raw' in dataOut:
|
|
2242
|
+
# move order_raw to the second column
|
|
2243
|
+
dataOut.remove('order_raw')
|
|
2244
|
+
dataOut.append('order_raw')
|
|
2245
|
+
# do the necessary analysis on the data
|
|
2246
|
+
for thisDataOutN, thisDataOut in enumerate(dataOut):
|
|
2247
|
+
dataType, analType = thisDataOut.rsplit('_', 1)
|
|
2248
|
+
if not dataType in self.data:
|
|
2249
|
+
# that analysis can't be done
|
|
2250
|
+
dataOutInvalid.append(thisDataOut)
|
|
2251
|
+
continue
|
|
2252
|
+
|
|
2253
|
+
if self.trialWeights is None:
|
|
2254
|
+
thisData = self.data[dataType]
|
|
2255
|
+
else:
|
|
2256
|
+
# BF_202302210_trialHandlerExt_save_nonnumeric_excel
|
|
2257
|
+
# Allow saving non-numeric data to the excel format
|
|
2258
|
+
# Previous case: masked arrays for numeric data
|
|
2259
|
+
if self.data.isNumeric[dataType]:
|
|
2260
|
+
resizedData = np.ma.masked_array(
|
|
2261
|
+
np.zeros((len(self.trialList),
|
|
2262
|
+
max(self.trialWeights) * self.nReps)),
|
|
2263
|
+
np.ones((len(self.trialList),
|
|
2264
|
+
max(self.trialWeights) * self.nReps),
|
|
2265
|
+
dtype=bool))
|
|
2266
|
+
for curTrialIndex in range(len(self.trialList)):
|
|
2267
|
+
thisDataChunk = self.data[dataType][
|
|
2268
|
+
idx_data == curTrialIndex, :]
|
|
2269
|
+
padWidth = (max(self.trialWeights) * self.nReps -
|
|
2270
|
+
np.prod(thisDataChunk.shape))
|
|
2271
|
+
thisDataChunkRowPadded = np.pad(
|
|
2272
|
+
thisDataChunk.transpose().flatten().data,
|
|
2273
|
+
(0, padWidth), mode='constant',
|
|
2274
|
+
constant_values=(0, 0))
|
|
2275
|
+
thisDataChunkRowPaddedMask = np.pad(
|
|
2276
|
+
thisDataChunk.transpose().flatten().mask,
|
|
2277
|
+
(0, padWidth), mode='constant',
|
|
2278
|
+
constant_values=(0, True))
|
|
2279
|
+
|
|
2280
|
+
thisDataChunkRow = np.ma.masked_array(
|
|
2281
|
+
thisDataChunkRowPadded,
|
|
2282
|
+
mask=thisDataChunkRowPaddedMask)
|
|
2283
|
+
resizedData[curTrialIndex, :] = thisDataChunkRow
|
|
2284
|
+
# For non-numeric data, Psychopy uses typical object arrays in-
|
|
2285
|
+
# stead of masked arrays. Adjust accordingly, filling with '--'
|
|
2286
|
+
# instead of masks
|
|
2287
|
+
else:
|
|
2288
|
+
resizedData = np.array(np.zeros((len(self.trialList),
|
|
2289
|
+
max(self.trialWeights) *
|
|
2290
|
+
self.nReps)), dtype='O')
|
|
2291
|
+
for curTrialIndex in range(len(self.trialList)):
|
|
2292
|
+
thisDataChunk = self.data[dataType][
|
|
2293
|
+
idx_data == curTrialIndex, :]
|
|
2294
|
+
padWidth = (max(self.trialWeights) * self.nReps -
|
|
2295
|
+
np.prod(thisDataChunk.shape))
|
|
2296
|
+
thisDataChunkRowPadded = np.pad(
|
|
2297
|
+
thisDataChunk.transpose().flatten().data,
|
|
2298
|
+
(0, padWidth), mode='constant',
|
|
2299
|
+
constant_values=('--', '--'))
|
|
2300
|
+
resizedData[curTrialIndex, :] = thisDataChunkRowPadded
|
|
2301
|
+
|
|
2302
|
+
thisData = resizedData
|
|
2303
|
+
|
|
2304
|
+
# set the header
|
|
2305
|
+
dataHead.append(dataType + '_' + analType)
|
|
2306
|
+
# analyse thisData using numpy module
|
|
2307
|
+
if analType in dir(np):
|
|
2308
|
+
try:
|
|
2309
|
+
# this will fail if we try to take mean of a string
|
|
2310
|
+
if analType == 'std':
|
|
2311
|
+
thisAnal = np.std(thisData, axis=1, ddof=0)
|
|
2312
|
+
# normalise by N-1 instead. This should work by
|
|
2313
|
+
# setting ddof=1 but doesn't as of 08/2010
|
|
2314
|
+
# (because of using a masked array?)
|
|
2315
|
+
N = thisData.shape[1]
|
|
2316
|
+
if N == 1:
|
|
2317
|
+
thisAnal *= 0 # prevent a divide-by-zero error
|
|
2318
|
+
else:
|
|
2319
|
+
sqrt = np.sqrt
|
|
2320
|
+
thisAnal = thisAnal * sqrt(N) / sqrt(N - 1)
|
|
2321
|
+
else:
|
|
2322
|
+
thisAnal = eval("np.%s(thisData,1)" % analType)
|
|
2323
|
+
except Exception:
|
|
2324
|
+
# that analysis doesn't work
|
|
2325
|
+
dataHead.remove(dataType + '_' + analType)
|
|
2326
|
+
dataOutInvalid.append(thisDataOut)
|
|
2327
|
+
continue # to next analysis
|
|
2328
|
+
elif analType == 'raw':
|
|
2329
|
+
thisAnal = thisData
|
|
2330
|
+
else:
|
|
2331
|
+
raise AttributeError('You can only use analyses from numpy')
|
|
2332
|
+
# add extra cols to header if necess
|
|
2333
|
+
if len(thisAnal.shape) > 1:
|
|
2334
|
+
for n in range(thisAnal.shape[1] - 1):
|
|
2335
|
+
dataHead.append("")
|
|
2336
|
+
dataAnal[thisDataOut] = thisAnal
|
|
2337
|
+
|
|
2338
|
+
# remove invalid analyses (e.g. average of a string)
|
|
2339
|
+
for invalidAnal in dataOutInvalid:
|
|
2340
|
+
dataOut.remove(invalidAnal)
|
|
2341
|
+
return dataOut, dataAnal, dataHead
|
|
2342
|
+
|
|
2343
|
+
def saveAsWideText(self,
|
|
2344
|
+
fileName,
|
|
2345
|
+
delim='\t',
|
|
2346
|
+
matrixOnly=False,
|
|
2347
|
+
appendFile=True,
|
|
2348
|
+
encoding='utf-8-sig',
|
|
2349
|
+
fileCollisionMethod='rename'):
|
|
2350
|
+
"""Write a text file with the session, stimulus, and data values
|
|
2351
|
+
from each trial in chronological order.
|
|
2352
|
+
|
|
2353
|
+
That is, unlike 'saveAsText' and 'saveAsExcel':
|
|
2354
|
+
- each row comprises information from only a single trial.
|
|
2355
|
+
- no summarizing is done (such as collapsing to produce mean and
|
|
2356
|
+
standard deviation values across trials).
|
|
2357
|
+
|
|
2358
|
+
This 'wide' format, as expected by R for creating dataframes, and
|
|
2359
|
+
various other analysis programs, means that some information must
|
|
2360
|
+
be repeated on every row.
|
|
2361
|
+
|
|
2362
|
+
In particular, if the trialHandler's 'extraInfo' exists, then each
|
|
2363
|
+
entry in there occurs in every row. In builder, this will include
|
|
2364
|
+
any entries in the 'Experiment info' field of the
|
|
2365
|
+
'Experiment settings' dialog. In Coder, this information can be set
|
|
2366
|
+
using something like::
|
|
2367
|
+
|
|
2368
|
+
myTrialHandler.extraInfo = {'SubjID':'Joan Smith',
|
|
2369
|
+
'Group':'Control'}
|
|
2370
|
+
|
|
2371
|
+
:Parameters:
|
|
2372
|
+
|
|
2373
|
+
fileName:
|
|
2374
|
+
if extension is not specified, '.csv' will be appended if
|
|
2375
|
+
the delimiter is ',', else '.txt' will be appended.
|
|
2376
|
+
Can include path info.
|
|
2377
|
+
|
|
2378
|
+
delim:
|
|
2379
|
+
allows the user to use a delimiter other than the default
|
|
2380
|
+
tab ("," is popular with file extension ".csv")
|
|
2381
|
+
|
|
2382
|
+
matrixOnly:
|
|
2383
|
+
outputs the data with no header row.
|
|
2384
|
+
|
|
2385
|
+
appendFile:
|
|
2386
|
+
will add this output to the end of the specified file if
|
|
2387
|
+
it already exists.
|
|
2388
|
+
|
|
2389
|
+
fileCollisionMethod:
|
|
2390
|
+
Collision method passed to
|
|
2391
|
+
:func:`~psychopy.tools.fileerrortools.handleFileCollision`
|
|
2392
|
+
|
|
2393
|
+
encoding:
|
|
2394
|
+
The encoding to use when saving a the file.
|
|
2395
|
+
Defaults to `utf-8-sig`.
|
|
2396
|
+
|
|
2397
|
+
"""
|
|
2398
|
+
if self.thisTrialN < 0 and self.thisRepN < 0:
|
|
2399
|
+
# if both are < 1 we haven't started
|
|
2400
|
+
logging.info('TrialHandler.saveAsWideText called but no trials'
|
|
2401
|
+
' completed. Nothing saved')
|
|
2402
|
+
return -1
|
|
2403
|
+
|
|
2404
|
+
# set default delimiter if none given
|
|
2405
|
+
if delim is None:
|
|
2406
|
+
delim = genDelimiter(fileName)
|
|
2407
|
+
|
|
2408
|
+
# create the file or send to stdout
|
|
2409
|
+
fileName = genFilenameFromDelimiter(fileName, delim)
|
|
2410
|
+
f = openOutputFile(fileName=fileName, append=appendFile,
|
|
2411
|
+
fileCollisionMethod=fileCollisionMethod,
|
|
2412
|
+
encoding=encoding)
|
|
2413
|
+
|
|
2414
|
+
# collect parameter names related to the stimuli:
|
|
2415
|
+
if self.trialList[0]:
|
|
2416
|
+
header = list(self.trialList[0].keys())
|
|
2417
|
+
else:
|
|
2418
|
+
header = []
|
|
2419
|
+
# and then add parameter names related to data (e.g. RT)
|
|
2420
|
+
header.extend(self.data.dataTypes)
|
|
2421
|
+
|
|
2422
|
+
# loop through each trial, gathering the actual values:
|
|
2423
|
+
dataOut = []
|
|
2424
|
+
trialCount = 0
|
|
2425
|
+
# total number of trials = number of trialtypes * number of
|
|
2426
|
+
# repetitions:
|
|
2427
|
+
|
|
2428
|
+
repsPerType = {}
|
|
2429
|
+
for rep in range(self.nReps):
|
|
2430
|
+
if self.trialWeights is None:
|
|
2431
|
+
nRows = len(self.trialList)
|
|
2432
|
+
else:
|
|
2433
|
+
nRows = sum(self.trialWeights)
|
|
2434
|
+
|
|
2435
|
+
for trialN in range(nRows):
|
|
2436
|
+
# find out what trial type was on this trial
|
|
2437
|
+
trialTypeIndex = self.sequenceIndices[trialN, rep]
|
|
2438
|
+
# determine which repeat it is for this trial
|
|
2439
|
+
if trialTypeIndex not in repsPerType:
|
|
2440
|
+
repsPerType[trialTypeIndex] = 0
|
|
2441
|
+
else:
|
|
2442
|
+
repsPerType[trialTypeIndex] += 1
|
|
2443
|
+
|
|
2444
|
+
# create a dictionary representing each trial:
|
|
2445
|
+
# this is wide format, so we want fixed information (e.g.
|
|
2446
|
+
# subject ID, date, etc) repeated every line if it exists:
|
|
2447
|
+
if self.extraInfo != None:
|
|
2448
|
+
nextEntry = self.extraInfo.copy()
|
|
2449
|
+
else:
|
|
2450
|
+
nextEntry = {}
|
|
2451
|
+
|
|
2452
|
+
# add a trial number so the original order of the data can
|
|
2453
|
+
# always be recovered if sorted during analysis:
|
|
2454
|
+
trialCount += 1
|
|
2455
|
+
nextEntry["TrialNumber"] = trialCount
|
|
2456
|
+
|
|
2457
|
+
# what repeat are we on for this trial type?
|
|
2458
|
+
trep = repsPerType[trialTypeIndex]
|
|
2459
|
+
# collect the value from each trial of the vars in the header:
|
|
2460
|
+
tti = trialTypeIndex
|
|
2461
|
+
for prmName in header:
|
|
2462
|
+
# the header includes both trial and data variables, so
|
|
2463
|
+
# need to check before accessing:
|
|
2464
|
+
if self.trialList[tti] and prmName in self.trialList[tti]:
|
|
2465
|
+
nextEntry[prmName] = self.trialList[tti][prmName]
|
|
2466
|
+
elif prmName in self.data:
|
|
2467
|
+
if self.trialWeights is None:
|
|
2468
|
+
nextEntry[prmName] = self.data[prmName][tti][trep]
|
|
2469
|
+
else:
|
|
2470
|
+
firstRowIndex = sum(self.trialWeights[:tti])
|
|
2471
|
+
_tw = self.trialWeights[tti]
|
|
2472
|
+
row = firstRowIndex + rep % _tw
|
|
2473
|
+
col = int(rep // _tw)
|
|
2474
|
+
nextEntry[prmName] = self.data[prmName][row][col]
|
|
2475
|
+
else:
|
|
2476
|
+
# allow a null value if this parameter wasn't
|
|
2477
|
+
# explicitly stored on this trial:
|
|
2478
|
+
nextEntry[prmName] = ''
|
|
2479
|
+
|
|
2480
|
+
# store this trial's data
|
|
2481
|
+
dataOut.append(nextEntry)
|
|
2482
|
+
|
|
2483
|
+
# get the extra 'wide' parameter names into the header line:
|
|
2484
|
+
header.insert(0, "TrialNumber")
|
|
2485
|
+
if self.extraInfo is not None:
|
|
2486
|
+
for key in self.extraInfo:
|
|
2487
|
+
header.insert(0, key)
|
|
2488
|
+
|
|
2489
|
+
# write a header row:
|
|
2490
|
+
if not matrixOnly:
|
|
2491
|
+
f.write(delim.join(header) + '\n')
|
|
2492
|
+
# write the data matrix:
|
|
2493
|
+
for trial in dataOut:
|
|
2494
|
+
line = delim.join([str(trial[prm]) for prm in header])
|
|
2495
|
+
f.write(line + '\n')
|
|
2496
|
+
|
|
2497
|
+
if (fileName is not None) and (fileName != 'stdout'):
|
|
2498
|
+
f.close()
|
|
2499
|
+
logging.info('saved wide-format data to %s' % f.name)
|
|
2500
|
+
|
|
2501
|
+
def saveAsJson(self,
|
|
2502
|
+
fileName=None,
|
|
2503
|
+
encoding='utf-8',
|
|
2504
|
+
fileCollisionMethod='rename'):
|
|
2505
|
+
raise NotImplementedError('Not implemented for TrialHandlerExt.')
|