psychopy 2024.2.5__py3-none-any.whl → 2025.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of psychopy might be problematic. Click here for more details.

Files changed (860) hide show
  1. psychopy/CHANGELOG.txt +4 -4
  2. psychopy/GIT_SHA +1 -1
  3. psychopy/LICENSE.txt +1 -1
  4. psychopy/VERSION +1 -1
  5. psychopy/__init__.py +10 -7
  6. psychopy/alerts/__init__.py +1 -1
  7. psychopy/alerts/_alerts.py +53 -17
  8. psychopy/alerts/_errorHandler.py +3 -4
  9. psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
  10. psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
  11. psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
  12. psychopy/alerts/alertsCatalogue/alertCategories.yaml +8 -1
  13. psychopy/alerts/alertsCatalogue/alertmsg.py +1 -1
  14. psychopy/alerts/alerttools.py +0 -16
  15. psychopy/app/Resources/betasplash.png +0 -0
  16. psychopy/app/Resources/betasplash@2x.png +0 -0
  17. psychopy/app/Resources/classic/case.png +0 -0
  18. psychopy/app/Resources/classic/case@2x.png +0 -0
  19. psychopy/app/Resources/classic/fileaudio.png +0 -0
  20. psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
  21. psychopy/app/Resources/classic/filecss.png +0 -0
  22. psychopy/app/Resources/classic/filecss@2x.png +0 -0
  23. psychopy/app/Resources/classic/filecsv.png +0 -0
  24. psychopy/app/Resources/classic/filecsv@2x.png +0 -0
  25. psychopy/app/Resources/classic/filedesign.png +0 -0
  26. psychopy/app/Resources/classic/filedesign@2x.png +0 -0
  27. psychopy/app/Resources/classic/filefont.png +0 -0
  28. psychopy/app/Resources/classic/filefont@2x.png +0 -0
  29. psychopy/app/Resources/classic/filegit.png +0 -0
  30. psychopy/app/Resources/classic/filegit@2x.png +0 -0
  31. psychopy/app/Resources/classic/filehtml.png +0 -0
  32. psychopy/app/Resources/classic/filehtml@2x.png +0 -0
  33. psychopy/app/Resources/classic/fileimage.png +0 -0
  34. psychopy/app/Resources/classic/fileimage@2x.png +0 -0
  35. psychopy/app/Resources/classic/fileinfo.png +0 -0
  36. psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
  37. psychopy/app/Resources/classic/filejs.png +0 -0
  38. psychopy/app/Resources/classic/filejs@2x.png +0 -0
  39. psychopy/app/Resources/classic/filejson.png +0 -0
  40. psychopy/app/Resources/classic/filejson@2x.png +0 -0
  41. psychopy/app/Resources/classic/filepkg.png +0 -0
  42. psychopy/app/Resources/classic/filepkg@2x.png +0 -0
  43. psychopy/app/Resources/classic/filepsyexp.png +0 -0
  44. psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
  45. psychopy/app/Resources/classic/filepy.png +0 -0
  46. psychopy/app/Resources/classic/filepy@2x.png +0 -0
  47. psychopy/app/Resources/classic/filetxt.png +0 -0
  48. psychopy/app/Resources/classic/filetxt@2x.png +0 -0
  49. psychopy/app/Resources/classic/fileunknown.png +0 -0
  50. psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
  51. psychopy/app/Resources/classic/filevideo.png +0 -0
  52. psychopy/app/Resources/classic/filevideo@2x.png +0 -0
  53. psychopy/app/Resources/classic/find.png +0 -0
  54. psychopy/app/Resources/classic/find@2x.png +0 -0
  55. psychopy/app/Resources/classic/loop.png +0 -0
  56. psychopy/app/Resources/classic/loop@2x.png +0 -0
  57. psychopy/app/Resources/classic/regex.png +0 -0
  58. psychopy/app/Resources/classic/regex@2x.png +0 -0
  59. psychopy/app/Resources/dark/case.png +0 -0
  60. psychopy/app/Resources/dark/case@2x.png +0 -0
  61. psychopy/app/Resources/dark/fileaudio.png +0 -0
  62. psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
  63. psychopy/app/Resources/dark/filecss.png +0 -0
  64. psychopy/app/Resources/dark/filecss@2x.png +0 -0
  65. psychopy/app/Resources/dark/filecsv.png +0 -0
  66. psychopy/app/Resources/dark/filecsv@2x.png +0 -0
  67. psychopy/app/Resources/dark/filedesign.png +0 -0
  68. psychopy/app/Resources/dark/filedesign@2x.png +0 -0
  69. psychopy/app/Resources/dark/filefont.png +0 -0
  70. psychopy/app/Resources/dark/filefont@2x.png +0 -0
  71. psychopy/app/Resources/dark/filegit.png +0 -0
  72. psychopy/app/Resources/dark/filegit@2x.png +0 -0
  73. psychopy/app/Resources/dark/filehtml.png +0 -0
  74. psychopy/app/Resources/dark/filehtml@2x.png +0 -0
  75. psychopy/app/Resources/dark/fileimage.png +0 -0
  76. psychopy/app/Resources/dark/fileimage@2x.png +0 -0
  77. psychopy/app/Resources/dark/fileinfo.png +0 -0
  78. psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
  79. psychopy/app/Resources/dark/filejs.png +0 -0
  80. psychopy/app/Resources/dark/filejs@2x.png +0 -0
  81. psychopy/app/Resources/dark/filejson.png +0 -0
  82. psychopy/app/Resources/dark/filejson@2x.png +0 -0
  83. psychopy/app/Resources/dark/filepkg.png +0 -0
  84. psychopy/app/Resources/dark/filepkg@2x.png +0 -0
  85. psychopy/app/Resources/dark/filepsyexp.png +0 -0
  86. psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
  87. psychopy/app/Resources/dark/filepy.png +0 -0
  88. psychopy/app/Resources/dark/filepy@2x.png +0 -0
  89. psychopy/app/Resources/dark/filetxt.png +0 -0
  90. psychopy/app/Resources/dark/filetxt@2x.png +0 -0
  91. psychopy/app/Resources/dark/fileunknown.png +0 -0
  92. psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
  93. psychopy/app/Resources/dark/filevideo.png +0 -0
  94. psychopy/app/Resources/dark/filevideo@2x.png +0 -0
  95. psychopy/app/Resources/dark/find.png +0 -0
  96. psychopy/app/Resources/dark/find@2x.png +0 -0
  97. psychopy/app/Resources/dark/loop.png +0 -0
  98. psychopy/app/Resources/dark/loop@2x.png +0 -0
  99. psychopy/app/Resources/dark/regex.png +0 -0
  100. psychopy/app/Resources/dark/regex@2x.png +0 -0
  101. psychopy/app/Resources/light/case.png +0 -0
  102. psychopy/app/Resources/light/case@2x.png +0 -0
  103. psychopy/app/Resources/light/fileaudio.png +0 -0
  104. psychopy/app/Resources/light/fileaudio@2x.png +0 -0
  105. psychopy/app/Resources/light/filecss.png +0 -0
  106. psychopy/app/Resources/light/filecss@2x.png +0 -0
  107. psychopy/app/Resources/light/filecsv.png +0 -0
  108. psychopy/app/Resources/light/filecsv@2x.png +0 -0
  109. psychopy/app/Resources/light/filedesign.png +0 -0
  110. psychopy/app/Resources/light/filedesign@2x.png +0 -0
  111. psychopy/app/Resources/light/filefont.png +0 -0
  112. psychopy/app/Resources/light/filefont@2x.png +0 -0
  113. psychopy/app/Resources/light/filegit.png +0 -0
  114. psychopy/app/Resources/light/filegit@2x.png +0 -0
  115. psychopy/app/Resources/light/filehtml.png +0 -0
  116. psychopy/app/Resources/light/filehtml@2x.png +0 -0
  117. psychopy/app/Resources/light/fileimage.png +0 -0
  118. psychopy/app/Resources/light/fileimage@2x.png +0 -0
  119. psychopy/app/Resources/light/fileinfo.png +0 -0
  120. psychopy/app/Resources/light/fileinfo@2x.png +0 -0
  121. psychopy/app/Resources/light/filejs.png +0 -0
  122. psychopy/app/Resources/light/filejs@2x.png +0 -0
  123. psychopy/app/Resources/light/filejson.png +0 -0
  124. psychopy/app/Resources/light/filejson@2x.png +0 -0
  125. psychopy/app/Resources/light/filepkg.png +0 -0
  126. psychopy/app/Resources/light/filepkg@2x.png +0 -0
  127. psychopy/app/Resources/light/filepsyexp.png +0 -0
  128. psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
  129. psychopy/app/Resources/light/filepy.png +0 -0
  130. psychopy/app/Resources/light/filepy@2x.png +0 -0
  131. psychopy/app/Resources/light/filetxt.png +0 -0
  132. psychopy/app/Resources/light/filetxt@2x.png +0 -0
  133. psychopy/app/Resources/light/fileunknown.png +0 -0
  134. psychopy/app/Resources/light/fileunknown@2x.png +0 -0
  135. psychopy/app/Resources/light/filevideo.png +0 -0
  136. psychopy/app/Resources/light/filevideo@2x.png +0 -0
  137. psychopy/app/Resources/light/find.png +0 -0
  138. psychopy/app/Resources/light/find@2x.png +0 -0
  139. psychopy/app/Resources/light/loop.png +0 -0
  140. psychopy/app/Resources/light/loop@2x.png +0 -0
  141. psychopy/app/Resources/light/regex.png +0 -0
  142. psychopy/app/Resources/light/regex@2x.png +0 -0
  143. psychopy/app/Resources/routine_templates/Basic.psyexp +0 -1
  144. psychopy/app/Resources/routine_templates/Misc.psyexp +0 -1
  145. psychopy/app/Resources/routine_templates/Online.psyexp +0 -2
  146. psychopy/app/Resources/routine_templates/Trials.psyexp +0 -1
  147. psychopy/app/Resources/splash.png +0 -0
  148. psychopy/app/Resources/splash@2x.png +0 -0
  149. psychopy/app/__init__.py +49 -8
  150. psychopy/app/__main__.py +3 -0
  151. psychopy/app/_psychopyApp.py +134 -125
  152. psychopy/app/builder/builder.py +42 -22
  153. psychopy/app/builder/dialogs/__init__.py +44 -11
  154. psychopy/app/builder/dialogs/dlgsCode.py +1 -1
  155. psychopy/app/builder/dialogs/dlgsConditions.py +1 -1
  156. psychopy/app/builder/dialogs/findDlg.py +106 -20
  157. psychopy/app/builder/dialogs/paramCtrls.py +42 -1
  158. psychopy/app/builder/validators.py +1 -1
  159. psychopy/app/coder/codeEditorBase.py +8 -8
  160. psychopy/app/coder/coder.py +32 -29
  161. psychopy/app/coder/fileBrowser.py +68 -22
  162. psychopy/app/coder/folding.py +1 -1
  163. psychopy/app/coder/psychoParser.py +1 -1
  164. psychopy/app/coder/repl.py +1 -1
  165. psychopy/app/coder/sourceTree.py +1 -1
  166. psychopy/app/connections/__init__.py +1 -1
  167. psychopy/app/connections/news.py +1 -1
  168. psychopy/app/connections/sendusage.py +1 -1
  169. psychopy/app/connections/updates.py +1 -1
  170. psychopy/app/console.py +1 -1
  171. psychopy/app/errorDlg.py +1 -1
  172. psychopy/app/frametracker.py +1 -1
  173. psychopy/app/idle.py +1 -1
  174. psychopy/app/jobs.py +5 -2
  175. psychopy/app/linuxconfig/__init__.py +1 -1
  176. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  177. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4 -4
  178. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  179. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  180. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  181. psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +3 -3
  182. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  183. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  184. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  185. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  186. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +4 -4
  187. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  188. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +4 -4
  189. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  190. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +4 -4
  191. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  192. psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +2 -2
  193. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  194. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +1 -1
  195. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  196. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  197. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +2 -2
  198. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  199. psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +2 -2
  200. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  201. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +2 -2
  202. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  203. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  204. psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +2 -2
  205. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  206. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3421 -2396
  207. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  208. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  209. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +2 -2
  210. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  211. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  212. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  213. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  214. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +4 -4
  215. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  216. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  217. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  218. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +2 -2
  219. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  220. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +2 -2
  221. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  222. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +3 -3
  223. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  224. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +2 -2
  225. psychopy/app/{builder/localizedStrings.py → localizedStrings.py} +173 -26
  226. psychopy/app/pavlovia_ui/__init__.py +1 -1
  227. psychopy/app/pavlovia_ui/_base.py +1 -1
  228. psychopy/app/pavlovia_ui/functions.py +1 -1
  229. psychopy/app/pavlovia_ui/menu.py +1 -1
  230. psychopy/app/pavlovia_ui/project.py +1 -1
  231. psychopy/app/pavlovia_ui/search.py +1 -1
  232. psychopy/app/pavlovia_ui/sync.py +1 -1
  233. psychopy/app/pavlovia_ui/user.py +1 -1
  234. psychopy/app/plugin_manager/dialog.py +34 -96
  235. psychopy/app/plugin_manager/packages.py +10 -14
  236. psychopy/app/plugin_manager/plugins.py +64 -4
  237. psychopy/app/preferencesDlg.py +12 -37
  238. psychopy/app/psychopyApp.py +130 -44
  239. psychopy/app/ribbon.py +1 -0
  240. psychopy/app/runner/runner.py +19 -7
  241. psychopy/app/runner/scriptProcess.py +11 -6
  242. psychopy/app/stdout/stdOutRich.py +9 -2
  243. psychopy/app/themes/fonts.py +1 -1
  244. psychopy/app/themes/icons.py +2 -38
  245. psychopy/app/ui/__init__.py +1 -1
  246. psychopy/app/utils.py +3 -3
  247. psychopy/assets/default.mp3 +0 -0
  248. psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
  249. psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
  250. psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
  251. psychopy/assets/fonts/NotoSans-Regular.ttf +0 -0
  252. psychopy/assets/voicekeyThresholdStim.wav +0 -0
  253. psychopy/clock.py +4 -1
  254. psychopy/colors.py +2 -0
  255. psychopy/core.py +1 -1
  256. psychopy/data/base.py +1 -1
  257. psychopy/data/experiment.py +151 -46
  258. psychopy/data/routine.py +27 -1
  259. psychopy/data/staircase.py +2 -1
  260. psychopy/data/trial.py +62 -14
  261. psychopy/data/utils.py +1 -1
  262. psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +333 -218
  263. psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +261 -239
  264. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +319 -180
  265. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +204 -116
  266. psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
  267. psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
  268. psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
  269. psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
  270. psychopy/demos/builder/Experiments/BART/bart.psyexp +779 -866
  271. psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +242 -180
  272. psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +419 -406
  273. psychopy/demos/builder/Experiments/dragAndDrop/README.md +2 -37
  274. psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +460 -1204
  275. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
  276. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
  277. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
  278. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
  279. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
  280. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
  281. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
  282. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
  283. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
  284. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
  285. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
  286. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
  287. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
  288. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
  289. psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +583 -542
  290. psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +458 -427
  291. psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +588 -550
  292. psychopy/demos/builder/Experiments/stroop/stroop.psyexp +303 -207
  293. psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +390 -215
  294. psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +390 -215
  295. psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +357 -331
  296. psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -2
  297. psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +287 -277
  298. psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +370 -320
  299. psychopy/demos/builder/Feature Demos/noise/noise.psyexp +452 -399
  300. psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +168 -133
  301. psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +4 -3
  302. psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +420 -392
  303. psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +917 -871
  304. psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
  305. psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +200 -0
  306. psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +25 -9
  307. psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +372 -361
  308. psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +25 -9
  309. psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +320 -235
  310. psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +790 -651
  311. psychopy/demos/builder/Hardware/camera/camera.psyexp +326 -246
  312. psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +432 -327
  313. psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +440 -321
  314. psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +190 -181
  315. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +323 -312
  316. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
  317. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp +312 -0
  318. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +329 -273
  319. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
  320. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
  321. psychopy/demos/builder/Hardware/microphone/microphone.psyexp +450 -404
  322. psychopy/demos/builder/Hardware/pump/pump.psyexp +593 -329
  323. psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
  324. psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +336 -274
  325. psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +200 -149
  326. psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -279
  327. psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +677 -564
  328. psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +214 -158
  329. psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +195 -146
  330. psychopy/demos/coder/experiment control/runtimeInfo.py +1 -1
  331. psychopy/devices/__init__.py +1 -1
  332. psychopy/event.py +1 -1
  333. psychopy/exceptions.py +1 -1
  334. psychopy/experiment/__init__.py +1 -1
  335. psychopy/experiment/_experiment.py +30 -9
  336. psychopy/experiment/components/__init__.py +1 -6
  337. psychopy/experiment/components/_base.py +44 -19
  338. psychopy/experiment/components/aperture/__init__.py +1 -1
  339. psychopy/experiment/components/brush/__init__.py +2 -2
  340. psychopy/experiment/components/button/__init__.py +24 -28
  341. psychopy/experiment/components/camera/__init__.py +38 -39
  342. psychopy/experiment/components/code/__init__.py +1 -1
  343. psychopy/experiment/components/dots/__init__.py +1 -1
  344. psychopy/experiment/components/eyetracker_record/__init__.py +7 -3
  345. psychopy/experiment/components/form/__init__.py +3 -3
  346. psychopy/experiment/components/grating/__init__.py +1 -1
  347. psychopy/experiment/components/image/__init__.py +1 -1
  348. psychopy/experiment/components/joyButtons/__init__.py +2 -2
  349. psychopy/experiment/components/joyButtons/virtualJoyButtons.py +1 -1
  350. psychopy/experiment/components/joystick/__init__.py +3 -3
  351. psychopy/experiment/components/joystick/virtualJoystick.py +1 -1
  352. psychopy/experiment/components/keyboard/__init__.py +98 -122
  353. psychopy/experiment/components/microphone/__init__.py +54 -98
  354. psychopy/experiment/components/mouse/__init__.py +92 -93
  355. psychopy/experiment/components/movie/__init__.py +28 -50
  356. psychopy/experiment/components/parallelOut/__init__.py +3 -3
  357. psychopy/experiment/components/polygon/__init__.py +2 -3
  358. psychopy/experiment/components/roi/__init__.py +2 -2
  359. psychopy/experiment/components/routineSettings/__init__.py +2 -0
  360. psychopy/experiment/components/serialOut/__init__.py +7 -7
  361. psychopy/experiment/components/settings/__init__.py +317 -313
  362. psychopy/experiment/components/settings/eyetracking.py +108 -0
  363. psychopy/experiment/components/slider/__init__.py +5 -5
  364. psychopy/experiment/components/sound/__init__.py +168 -78
  365. psychopy/experiment/components/soundsensor/__init__.py +361 -0
  366. psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
  367. psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
  368. psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
  369. psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
  370. psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
  371. psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
  372. psychopy/experiment/components/static/__init__.py +59 -33
  373. psychopy/experiment/components/text/__init__.py +2 -6
  374. psychopy/experiment/components/textbox/__init__.py +3 -7
  375. psychopy/experiment/components/unknown/__init__.py +2 -0
  376. psychopy/experiment/components/unknownPlugin/__init__.py +2 -0
  377. psychopy/experiment/exports.py +1 -1
  378. psychopy/experiment/flow.py +2 -2
  379. psychopy/experiment/localization.py +1 -1
  380. psychopy/experiment/loops.py +43 -10
  381. psychopy/experiment/params.py +6 -4
  382. psychopy/experiment/plugins.py +8 -1
  383. psychopy/experiment/py2js.py +1 -1
  384. psychopy/experiment/py2js_transpiler.py +1 -1
  385. psychopy/experiment/routines/__init__.py +1 -1
  386. psychopy/experiment/routines/_base.py +23 -24
  387. psychopy/experiment/routines/audioValidator/__init__.py +343 -0
  388. psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
  389. psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
  390. psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
  391. psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
  392. psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
  393. psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
  394. psychopy/experiment/routines/eyetracker_calibrate/__init__.py +76 -17
  395. psychopy/experiment/routines/eyetracker_validate/__init__.py +1 -1
  396. psychopy/experiment/routines/unknown/__init__.py +2 -0
  397. psychopy/experiment/routines/{photodiodeValidator → visualValidator}/__init__.py +89 -120
  398. psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
  399. psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
  400. psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
  401. psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
  402. psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
  403. psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
  404. psychopy/experiment/utils.py +1 -1
  405. psychopy/gui/__init__.py +1 -1
  406. psychopy/gui/qtgui.py +15 -6
  407. psychopy/gui/wxgui.py +1 -1
  408. psychopy/hardware/__init__.py +0 -1
  409. psychopy/hardware/base.py +147 -16
  410. psychopy/hardware/bbtk/__init__.py +10 -16
  411. psychopy/hardware/brainproducts.py +7 -13
  412. psychopy/hardware/button.py +21 -2
  413. psychopy/hardware/buttonbox/__init__.py +1 -1
  414. psychopy/hardware/camera/__init__.py +16 -3
  415. psychopy/hardware/cedrus.py +5 -16
  416. psychopy/hardware/crs/__init__.py +1 -1
  417. psychopy/hardware/crs/bits.py +36 -33
  418. psychopy/hardware/crs/colorcal.py +8 -11
  419. psychopy/hardware/crs/optical.py +7 -10
  420. psychopy/hardware/crs/shaders.py +18 -5
  421. psychopy/hardware/emotiv.py +1 -1
  422. psychopy/hardware/emulator.py +11 -5
  423. psychopy/hardware/exceptions.py +86 -0
  424. psychopy/hardware/forp.py +18 -23
  425. psychopy/hardware/gammasci.py +8 -3
  426. psychopy/hardware/iolab.py +8 -19
  427. psychopy/hardware/joystick/__init__.py +865 -266
  428. psychopy/hardware/joystick/_base.py +251 -0
  429. psychopy/hardware/joystick/backend_glfw.py +306 -0
  430. psychopy/hardware/joystick/backend_pyglet.py +309 -0
  431. psychopy/hardware/joystick/mappings.py +287 -0
  432. psychopy/hardware/keyboard.py +4 -2
  433. psychopy/hardware/labhackers.py +1 -1
  434. psychopy/hardware/labjacks.py +9 -13
  435. psychopy/hardware/{photodiode.py → lightsensor.py} +146 -203
  436. psychopy/hardware/listener.py +9 -8
  437. psychopy/hardware/manager.py +24 -35
  438. psychopy/hardware/microphone.py +534 -154
  439. psychopy/hardware/minolta.py +14 -4
  440. psychopy/hardware/mouse/__init__.py +1 -1
  441. psychopy/hardware/photometer/__init__.py +2 -2
  442. psychopy/hardware/pr.py +14 -4
  443. psychopy/hardware/qmix.py +18 -27
  444. psychopy/hardware/serialdevice.py +43 -12
  445. psychopy/hardware/soundsensor.py +473 -0
  446. psychopy/hardware/spatial/__init__.py +231 -0
  447. psychopy/hardware/speaker.py +298 -36
  448. psychopy/hardware/triggerbox/__init__.py +1 -1
  449. psychopy/hardware/triggerbox/base.py +1 -1
  450. psychopy/hardware/triggerbox/parallel.py +1 -1
  451. psychopy/info.py +1 -1
  452. psychopy/iohub/devices/eyetracker/__init__.py +10 -18
  453. psychopy/iohub/devices/eyetracker/calibration/procedure.py +15 -33
  454. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +1 -0
  455. psychopy/iohub/devices/mouse/linux2.py +2 -1
  456. psychopy/layout.py +1 -1
  457. psychopy/liaison.py +91 -39
  458. psychopy/locale_setup.py +11 -1
  459. psychopy/localization/__init__.py +1 -1
  460. psychopy/localization/_localization.py +1 -1
  461. psychopy/localization/messages.pot +2 -2
  462. psychopy/logging.py +14 -12
  463. psychopy/microphone.py +4 -3
  464. psychopy/misc.py +1 -1
  465. psychopy/monitors/MonitorCenter.py +3 -3
  466. psychopy/monitors/__init__.py +1 -1
  467. psychopy/monitors/calibData.py +1 -1
  468. psychopy/monitors/calibTools.py +3 -2
  469. psychopy/platform_specific/__init__.py +1 -1
  470. psychopy/platform_specific/darwin.py +1 -1
  471. psychopy/platform_specific/linux.py +1 -1
  472. psychopy/platform_specific/win32.py +1 -1
  473. psychopy/plugins/__init__.py +26 -17
  474. psychopy/plugins/util.py +65 -0
  475. psychopy/preferences/Darwin.spec +11 -3
  476. psychopy/preferences/FreeBSD.spec +11 -3
  477. psychopy/preferences/Linux.spec +11 -3
  478. psychopy/preferences/Windows.spec +11 -3
  479. psychopy/preferences/__init__.py +1 -1
  480. psychopy/preferences/baseNoArch.spec +11 -3
  481. psychopy/preferences/hints.py +78 -61
  482. psychopy/preferences/preferences.py +82 -13
  483. psychopy/projects/__init__.py +1 -1
  484. psychopy/projects/pavlovia.py +29 -13
  485. psychopy/scripts/psyexpCompile.py +1 -1
  486. psychopy/session.py +81 -8
  487. psychopy/sound/__init__.py +25 -10
  488. psychopy/sound/_base.py +134 -34
  489. psychopy/sound/audioclip.py +38 -15
  490. psychopy/sound/audiodevice.py +1 -1
  491. psychopy/sound/backend_ptb.py +53 -321
  492. psychopy/sound/backend_pygame.py +7 -3
  493. psychopy/sound/backend_pyo.py +53 -22
  494. psychopy/sound/backend_pysound.py +10 -27
  495. psychopy/sound/backend_sounddevice.py +33 -21
  496. psychopy/sound/exceptions.py +1 -1
  497. psychopy/sound/microphone.py +83 -5
  498. psychopy/sound/transcribe.py +3 -3
  499. psychopy/tests/data/test_basic_run.py +1 -0
  500. psychopy/tests/data/test_sounds/default_16000.wav +0 -0
  501. psychopy/tests/data/test_sounds/default_192000.wav +0 -0
  502. psychopy/tests/data/test_sounds/default_22050.wav +0 -0
  503. psychopy/tests/data/test_sounds/default_32000.wav +0 -0
  504. psychopy/tests/data/test_sounds/default_44100.wav +0 -0
  505. psychopy/tests/data/test_sounds/default_48000.wav +0 -0
  506. psychopy/tests/data/test_sounds/default_8000.wav +0 -0
  507. psychopy/tests/data/test_sounds/default_96000.wav +0 -0
  508. psychopy/tests/test_alerts/test_alerttools.py +2 -1
  509. psychopy/tests/test_app/test_command_line.py +65 -0
  510. psychopy/tests/test_data/test_TrialHandler2.py +18 -7
  511. psychopy/tests/test_demos/test_builder_demos.py +1 -1
  512. psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +5238 -4188
  513. psychopy/tests/test_experiment/needs_wx/test_components.py +1 -1
  514. psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
  515. psychopy/tests/test_experiment/test_components/test_all_components.py +1 -1
  516. psychopy/tests/test_experiment/test_components/test_base_components.py +26 -17
  517. psychopy/tests/test_experiment/test_loops.py +12 -4
  518. psychopy/tests/test_experiment/test_params.py +17 -4
  519. psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +2 -2
  520. psychopy/tests/test_hardware/test_photodiode.py +66 -0
  521. psychopy/tests/test_liaison/test_Liaison.py +4 -4
  522. psychopy/tests/test_misc/test_clock.py +2 -0
  523. psychopy/tests/test_misc/test_color.py +2 -0
  524. psychopy/tests/test_misc/test_event.py +1 -0
  525. psychopy/tests/test_plugins/__init__.py +0 -0
  526. psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
  527. psychopy/tests/test_sound/test_sound.py +111 -40
  528. psychopy/tests/test_tools/test_colorspacetools.py +24 -23
  529. psychopy/tests/test_tools/test_mathtools.py +9 -9
  530. psychopy/tests/test_tools/test_viewtools.py +101 -0
  531. psychopy/tests/test_validators/__init__.py +0 -0
  532. psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
  533. psychopy/tests/test_visual/test_all_stimuli.py +2 -2
  534. psychopy/tests/test_visual/test_basevisual.py +37 -7
  535. psychopy/tests/test_visual/test_button.py +2 -2
  536. psychopy/tests/test_visual/test_circle.py +10 -2
  537. psychopy/tests/test_visual/test_dots.py +1 -1
  538. psychopy/tests/test_visual/test_form.py +13 -13
  539. psychopy/tests/test_visual/test_gamma.py +3 -3
  540. psychopy/tests/test_visual/test_image.py +2 -2
  541. psychopy/tests/test_visual/test_progress.py +2 -2
  542. psychopy/tests/test_visual/test_roi.py +8 -2
  543. psychopy/tests/test_visual/test_shape.py +2 -2
  544. psychopy/tests/test_visual/test_slider.py +2 -2
  545. psychopy/tests/test_visual/test_target.py +2 -2
  546. psychopy/tests/test_visual/test_textbox.py +6 -8
  547. psychopy/tests/test_visual/test_winScalePos.py +6 -5
  548. psychopy/tests/test_visual/test_window.py +17 -0
  549. psychopy/tests/utils.py +51 -1
  550. psychopy/tools/__init__.py +1 -1
  551. psychopy/tools/arraytools.py +2 -2
  552. psychopy/tools/attributetools.py +52 -1
  553. psychopy/tools/audiotools.py +4 -1
  554. psychopy/tools/colorspacetools.py +6 -4
  555. psychopy/tools/coordinatetools.py +1 -1
  556. psychopy/tools/fileerrortools.py +21 -9
  557. psychopy/tools/filetools.py +2 -2
  558. psychopy/tools/fontmanager.py +47 -28
  559. psychopy/tools/gltools.py +2964 -558
  560. psychopy/tools/imagetools.py +1 -1
  561. psychopy/tools/mathtools.py +997 -127
  562. psychopy/tools/monitorunittools.py +7 -1
  563. psychopy/tools/movietools.py +1 -2
  564. psychopy/tools/pkgtools.py +157 -127
  565. psychopy/tools/plottools.py +1 -1
  566. psychopy/tools/rifttools.py +1 -1
  567. psychopy/tools/stereotools.py +1 -1
  568. psychopy/tools/stimulustools.py +172 -2
  569. psychopy/tools/stringtools.py +22 -2
  570. psychopy/tools/systemtools.py +1 -1
  571. psychopy/tools/typetools.py +1 -1
  572. psychopy/tools/unittools.py +1 -1
  573. psychopy/tools/versionchooser.py +3 -1
  574. psychopy/tools/viewtools.py +54 -70
  575. psychopy/tools/wizard.py +2 -2
  576. psychopy/validation/__init__.py +6 -0
  577. psychopy/validation/audio.py +74 -0
  578. psychopy/validation/visual.py +115 -0
  579. psychopy/visual/__init__.py +1 -4
  580. psychopy/visual/aperture.py +9 -6
  581. psychopy/visual/backends/__init__.py +1 -1
  582. psychopy/visual/backends/_base.py +1 -1
  583. psychopy/visual/backends/gamma.py +1 -1
  584. psychopy/visual/backends/glfwbackend.py +8 -12
  585. psychopy/visual/backends/pygamebackend.py +1 -1
  586. psychopy/visual/backends/pygletbackend.py +32 -11
  587. psychopy/visual/basevisual.py +93 -13
  588. psychopy/visual/brush.py +1 -1
  589. psychopy/visual/bufferimage.py +90 -10
  590. psychopy/visual/button.py +1 -1
  591. psychopy/visual/circle.py +12 -20
  592. psychopy/visual/custommouse.py +1 -1
  593. psychopy/visual/dot.py +80 -14
  594. psychopy/visual/elementarray.py +84 -10
  595. psychopy/visual/filters.py +1 -1
  596. psychopy/visual/form.py +43 -28
  597. psychopy/visual/grating.py +105 -25
  598. psychopy/visual/helpers.py +1 -1
  599. psychopy/visual/image.py +98 -20
  600. psychopy/visual/line.py +15 -25
  601. psychopy/visual/movie.py +1 -1
  602. psychopy/visual/movie2.py +4 -3
  603. psychopy/visual/movie3.py +4 -3
  604. psychopy/visual/movies/__init__.py +1 -1
  605. psychopy/visual/movies/frame.py +1 -1
  606. psychopy/visual/movies/metadata.py +1 -1
  607. psychopy/visual/movies/players/__init__.py +1 -1
  608. psychopy/visual/movies/players/_base.py +1 -1
  609. psychopy/visual/movies/players/ffpyplayer_player.py +2 -3
  610. psychopy/visual/nnlvs.py +9 -6
  611. psychopy/visual/noise.py +4 -16
  612. psychopy/visual/patch.py +4 -3
  613. psychopy/visual/pie.py +3 -14
  614. psychopy/visual/polygon.py +21 -28
  615. psychopy/visual/radial.py +4 -18
  616. psychopy/visual/ratingscale.py +4 -3
  617. psychopy/visual/rect.py +16 -25
  618. psychopy/visual/rift.py +8 -2
  619. psychopy/visual/secondorder.py +4 -16
  620. psychopy/visual/shaders.py +620 -286
  621. psychopy/visual/shape.py +281 -90
  622. psychopy/visual/simpleimage.py +1 -1
  623. psychopy/visual/slider.py +78 -25
  624. psychopy/visual/stim3d.py +5 -608
  625. psychopy/visual/text.py +13 -3
  626. psychopy/visual/textbox2/textbox2.py +188 -56
  627. psychopy/visual/vlcmoviestim.py +1 -1
  628. psychopy/visual/window.py +373 -200
  629. psychopy/web.py +1 -1
  630. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/METADATA +9 -9
  631. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/RECORD +644 -621
  632. psychopy/.DS_Store +0 -0
  633. psychopy/__init__.py.orig +0 -65
  634. psychopy/app/.DS_Store +0 -0
  635. psychopy/app/Resources/.DS_Store +0 -0
  636. psychopy/app/Resources/classic/filecsv16.png +0 -0
  637. psychopy/app/Resources/classic/fileimage16.png +0 -0
  638. psychopy/app/Resources/classic/fileunknown16.png +0 -0
  639. psychopy/app/Resources/dark/filecsv16.png +0 -0
  640. psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
  641. psychopy/app/Resources/dark/fileimage16.png +0 -0
  642. psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
  643. psychopy/app/Resources/dark/fileunknown16.png +0 -0
  644. psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
  645. psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
  646. psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
  647. psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
  648. psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  649. psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
  650. psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
  651. psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
  652. psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
  653. psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
  654. psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
  655. psychopy/app/Resources/light/filecsv16.png +0 -0
  656. psychopy/app/Resources/light/filecsv16@2x.png +0 -0
  657. psychopy/app/Resources/light/fileimage16.png +0 -0
  658. psychopy/app/Resources/light/fileimage16@2x.png +0 -0
  659. psychopy/app/Resources/light/fileunknown16.png +0 -0
  660. psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
  661. psychopy/app/Resources/psychopySplash.png +0 -0
  662. psychopy/app/Resources/psychopySplash@2x.png +0 -0
  663. psychopy/app/builder/builder.py.orig +0 -3932
  664. psychopy/app/builder/dialogs/__init__.py.orig +0 -1679
  665. psychopy/app/builder/dialogs/paramCtrls.py.orig +0 -713
  666. psychopy/app/colorpicker/__init__.py.orig +0 -411
  667. psychopy/app/locale/ar_001/.DS_Store +0 -0
  668. psychopy/app/locale/ar_001/LC_MESSAGE/.DS_Store +0 -0
  669. psychopy/core.py.orig +0 -169
  670. psychopy/demos/builder/.DS_Store +0 -0
  671. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +0 -330
  672. psychopy/demos/builder/Experiments/.DS_Store +0 -0
  673. psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
  674. psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +0 -61
  675. psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +0 -91
  676. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
  677. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
  678. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
  679. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
  680. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
  681. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
  682. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
  683. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
  684. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
  685. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
  686. psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
  687. psychopy/demos/builder/Tools/.DS_Store +0 -0
  688. psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
  689. psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
  690. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +0 -38
  691. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +0 -3418
  692. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
  693. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +0 -2
  694. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +0 -15
  695. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
  696. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +0 -562
  697. psychopy/demos/coder/.DS_Store +0 -0
  698. psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
  699. psychopy/demos/coder/iohub/.iohpid +0 -1
  700. psychopy/demos/coder/iohub/eyetracking/.iohpid +0 -1
  701. psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
  702. psychopy/demos/coder/stimuli/.DS_Store +0 -0
  703. psychopy/experiment/_experiment.py.orig +0 -1032
  704. psychopy/experiment/components/.DS_Store +0 -0
  705. psychopy/experiment/components/_base.py.orig +0 -823
  706. psychopy/experiment/components/form/.DS_Store +0 -0
  707. psychopy/experiment/components/microphone/__init__.py.orig +0 -490
  708. psychopy/experiment/components/settings/__init__.py.orig +0 -1337
  709. psychopy/experiment/components/textbox/__init__.py.orig +0 -310
  710. psychopy/experiment/components/webcam/.DS_Store +0 -0
  711. psychopy/experiment/components/webcam/light/.DS_Store +0 -0
  712. psychopy/experiment/loops.py.orig +0 -829
  713. psychopy/experiment/params.py.orig +0 -408
  714. psychopy/experiment/routine.py.orig +0 -503
  715. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
  716. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
  717. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
  718. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
  719. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
  720. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
  721. psychopy/hardware/.DS_Store +0 -0
  722. psychopy/hardware/brainproducts.py.orig +0 -680
  723. psychopy/hardware/iolab.py.orig +0 -238
  724. psychopy/iohub/datastore/__init__.py.orig +0 -443
  725. psychopy/iohub/datastore/util.py.orig +0 -692
  726. psychopy/iohub/devices/mouse/darwin.py.orig +0 -427
  727. psychopy/iohub/devices/mouse/linux2.py.orig +0 -198
  728. psychopy/preferences/.DS_Store +0 -0
  729. psychopy/projects/pavlovia.py.orig +0 -1295
  730. psychopy/tests/.DS_Store +0 -0
  731. psychopy/tests/data/.DS_Store +0 -0
  732. psychopy/tests/data/TestCircle_fill_local.png +0 -0
  733. psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
  734. psychopy/tests/data/aperture1_norm_local.png +0 -0
  735. psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
  736. psychopy/tests/data/beatandrcos_height_local.png +0 -0
  737. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  738. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  739. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  740. psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
  741. psychopy/tests/data/blend_add_height_local.png +0 -0
  742. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  743. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  744. psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
  745. psychopy/tests/data/blend_add_norm_local.png +0 -0
  746. psychopy/tests/data/blend_add_stencil_local.png +0 -0
  747. psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
  748. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  749. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  750. psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
  751. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  752. psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
  753. psychopy/tests/data/circleHex_height_local.png +0 -0
  754. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  755. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  756. psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
  757. psychopy/tests/data/circleHex_norm_local.png +0 -0
  758. psychopy/tests/data/circleHex_stencil_local.png +0 -0
  759. psychopy/tests/data/color_comparison_local.png +0 -0
  760. psychopy/tests/data/correctScript/.DS_Store +0 -0
  761. psychopy/tests/data/dots_height_local.png +0 -0
  762. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  763. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  764. psychopy/tests/data/dots_normNoShade_local.png +0 -0
  765. psychopy/tests/data/dots_norm_local.png +0 -0
  766. psychopy/tests/data/dots_stencil_local.png +0 -0
  767. psychopy/tests/data/elarray1_height_local.png +0 -0
  768. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  769. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  770. psychopy/tests/data/elarray1_norm_local.png +0 -0
  771. psychopy/tests/data/elarray1_stencil_local.png +0 -0
  772. psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
  773. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  774. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  775. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  776. psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
  777. psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
  778. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  779. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  780. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  781. psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
  782. psychopy/tests/data/gabor1_height_local.png +0 -0
  783. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  784. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  785. psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
  786. psychopy/tests/data/gabor1_norm_local.png +0 -0
  787. psychopy/tests/data/gabor1_stencil_local.png +0 -0
  788. psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
  789. psychopy/tests/data/imageAndGauss_height_local.png +0 -0
  790. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  791. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  792. psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
  793. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  794. psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
  795. psychopy/tests/data/movFrame1_stencil_local.png +0 -0
  796. psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
  797. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  798. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  799. psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
  800. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  801. psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
  802. psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
  803. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  804. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  805. psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
  806. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  807. psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
  808. psychopy/tests/data/numpyImage_height_local.png +0 -0
  809. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  810. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  811. psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
  812. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  813. psychopy/tests/data/numpyImage_stencil_local.png +0 -0
  814. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  815. psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
  816. psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
  817. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  818. psychopy/tests/data/shape2_1_stencil_local.png +0 -0
  819. psychopy/tests/data/text1_height_local.png +0 -0
  820. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  821. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  822. psychopy/tests/data/text1_norm_local.png +0 -0
  823. psychopy/tests/data/text1_stencil_local.png +0 -0
  824. psychopy/tests/data/wedge1_height_local.png +0 -0
  825. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  826. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  827. psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
  828. psychopy/tests/data/wedge1_norm_local.png +0 -0
  829. psychopy/tests/data/wedge1_stencil_local.png +0 -0
  830. psychopy/tests/test_app/.DS_Store +0 -0
  831. psychopy/tests/test_app/test_builder/.DS_Store +0 -0
  832. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +0 -177
  833. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
  834. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
  835. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +0 -168
  836. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
  837. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
  838. psychopy/tests/test_data/.DS_Store +0 -0
  839. psychopy/tests/test_hardware/test_CRS_BitsSharp.py +0 -67
  840. psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +0 -68
  841. psychopy/tests/test_hardware/test_CRS_bitsShaders.py +0 -110
  842. psychopy/tests/test_visual/test_image.py.orig +0 -219
  843. psychopy/visual/basevisual.py.orig +0 -1723
  844. psychopy/visual/form.py.orig +0 -1181
  845. psychopy/visual/text.py.orig +0 -752
  846. psychopy/visual/textbox2/textbox2.py.orig +0 -1315
  847. psychopy/visual/windowwarp.py.orig +0 -463
  848. /psychopy/{app/cortex.log → alerts/alertsCatalogue/3600.yaml} +0 -0
  849. /psychopy/{app/Resources → assets}/fonts/Arvo-Bold.ttf +0 -0
  850. /psychopy/{app/Resources → assets}/fonts/Arvo-BoldItalic.ttf +0 -0
  851. /psychopy/{app/Resources → assets}/fonts/Arvo-Italic.ttf +0 -0
  852. /psychopy/{app/Resources → assets}/fonts/Arvo-Regular.ttf +0 -0
  853. /psychopy/{app/Resources → assets}/fonts/DejaVuSerif.ttf +0 -0
  854. /psychopy/{app/Resources → assets}/fonts/IndieFlower-Regular.ttf +0 -0
  855. /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
  856. /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
  857. /psychopy/demos/builder/Experiments/{GoNoGo → goNoGo}/readme.md +0 -0
  858. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/WHEEL +0 -0
  859. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/entry_points.txt +0 -0
  860. {psychopy-2024.2.5.dist-info → psychopy-2025.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,12 +7,13 @@ from pathlib import Path
7
7
  from xml.etree.ElementTree import Element
8
8
  import re
9
9
  from psychopy import logging, plugins
10
+ from psychopy.preferences import prefs
10
11
  from psychopy.experiment.components import Param, _translate
12
+ from psychopy.experiment.components.settings.eyetracking import knownEyetrackerBackends
11
13
  from psychopy.experiment.routines import Routine, BaseStandaloneRoutine
12
14
  from psychopy.experiment.routines.eyetracker_calibrate import EyetrackerCalibrationRoutine
13
15
  from psychopy.experiment import utils as exputils
14
16
  from psychopy.monitors import Monitor
15
- from psychopy.iohub import util as ioUtil
16
17
  from psychopy.alerts import alert
17
18
  from psychopy.tools.filetools import genDelimiter
18
19
  from psychopy.data.utils import parsePipeSyntax
@@ -41,11 +42,6 @@ _numpyImports = ['sin', 'cos', 'tan', 'log', 'log10', 'pi', 'average',
41
42
  'sqrt', 'std', 'deg2rad', 'rad2deg', 'linspace', 'asarray']
42
43
  _numpyRandomImports = ['random', 'randint', 'normal', 'shuffle', 'choice as randchoice']
43
44
 
44
- # this is not a standard component - it will appear on toolbar not in
45
- # components panel
46
- ioDeviceMap = dict(ioUtil.getDeviceNames(device_name="eyetracker.hw"))
47
- ioDeviceMap['None'] = ""
48
-
49
45
  # Keyboard backend options
50
46
  keyboardBackendMap = {
51
47
  "ioHub": "iohub",
@@ -53,6 +49,9 @@ keyboardBackendMap = {
53
49
  "Pyglet": "event"
54
50
  }
55
51
 
52
+ # possible expInfo keys for participant ID
53
+ participantIdAliases = ('participant', 'Participant', 'Subject', 'Observer')
54
+
56
55
 
57
56
  # # customize the Proj ID Param class to
58
57
  # class ProjIDParam(Param):
@@ -79,6 +78,11 @@ class SettingsComponent:
79
78
  targets = ['PsychoPy', 'PsychoJS']
80
79
  iconFile = Path(__file__).parent / 'settings.png'
81
80
  tooltip = _translate("Edit settings for this experiment")
81
+ plugin = None
82
+ version = "0.0.0"
83
+ beta = False
84
+ # an experiment only has one SettingsComponent, so hide it from the Components panel
85
+ hidden = True
82
86
 
83
87
  def __init__(
84
88
  self, parentName, exp, expName='', fullScr=True, runMode=0, rush=False,
@@ -100,6 +104,7 @@ class SettingsComponent:
100
104
  savedDataFolder='', savedDataDelim='auto',
101
105
  clockFormat="float",
102
106
  useVersion='',
107
+ expVersion='',
103
108
  eyetracker="None",
104
109
  mgMove='CONTINUOUS', mgBlink='MIDDLE_BUTTON', mgSaccade=0.5,
105
110
  gpAddress='127.0.0.1', gpPort=4242,
@@ -114,13 +119,11 @@ class SettingsComponent:
114
119
  plPupilRemoteAddress="127.0.0.1",
115
120
  plPupilRemotePort=50020,
116
121
  plPupilRemoteTimeoutMs=1000,
117
- plPupilCaptureRecordingEnabled=True,
118
122
  plPupilCaptureRecordingLocation="",
119
123
  plCompanionAddress="neon.local",
120
124
  plCompanionPort=8080,
121
- plCompanionRecordingEnabled=True,
122
125
  ecSampleRate='default',
123
- keyboardBackend="ioHub",
126
+ keyboardBackend="PsychToolbox",
124
127
  filename=None, exportHTML='on Sync',
125
128
  endMessage=_translate("Thank you for your patience.")
126
129
  ):
@@ -144,7 +147,8 @@ class SettingsComponent:
144
147
  self.params = {}
145
148
  self.depends = []
146
149
  self.order = [
147
- 'Audio lib', 'Audio latency priority', "Force stereo", # Audio tab
150
+ 'expName', 'expVersion',
151
+ 'Audio lib', "Force stereo", # Audio tab
148
152
  'HTML path', 'exportHTML', 'Completed URL', 'Incomplete URL', 'End Message', 'Resources', # Online tab
149
153
  ]
150
154
  self.depends = []
@@ -166,6 +170,13 @@ class SettingsComponent:
166
170
  ),
167
171
  label=_translate("Experiment name")
168
172
  )
173
+ self.params['expVersion'] = Param(
174
+ expVersion, valType='str', inputType="single", categ='Basic',
175
+ hint=_translate(
176
+ "Version number of the experiment (a string). Just for your records if it's useful to store"
177
+ ),
178
+ label=_translate("Experiment version")
179
+ )
169
180
  self.params['runMode'] = Param(
170
181
  runMode, valType="code", inputType="choice", categ="Basic",
171
182
  allowedVals=[0, 1],
@@ -374,20 +385,6 @@ class SettingsComponent:
374
385
  hint=_translate("Which Python sound engine do you want to play your sounds?"),
375
386
  label=_translate("Audio library"), categ='Audio')
376
387
 
377
- audioLatencyLabels = [
378
- '0: ' + _translate('Latency not important'),
379
- '1: ' + _translate('Share low-latency driver'),
380
- '2: ' + _translate('Exclusive low-latency'),
381
- '3: ' + _translate('Aggressive low-latency'),
382
- '4: ' + _translate('Latency critical'),
383
- ]
384
- self.params['Audio latency priority'] = Param(
385
- '3', valType='str', inputType="choice",
386
- allowedVals=['0', '1', '2', '3', '4'],
387
- allowedLabels=audioLatencyLabels,
388
- hint=_translate("How important is audio latency for you? If essential then you may need to get all your sounds in correct formats."),
389
- label=_translate("Audio latency priority"), categ='Audio')
390
-
391
388
  # --- Data params ---
392
389
  self.order += [
393
390
  "Data filename",
@@ -541,8 +538,8 @@ class SettingsComponent:
541
538
  "Tobii Technology": ["tbModel", "tbLicenseFile", "tbSerialNo", "tbSampleRate"],
542
539
  "Pupil Labs": ["plPupillometryOnly", "plSurfaceName", "plConfidenceThreshold",
543
540
  "plPupilRemoteAddress", "plPupilRemotePort", "plPupilRemoteTimeoutMs",
544
- "plPupilCaptureRecordingEnabled", "plPupilCaptureRecordingLocation"],
545
- "Pupil Labs (Neon)": ["plCompanionAddress", "plCompanionPort", "plCompanionRecordingEnabled"],
541
+ "plPupilCaptureRecordingLocation"],
542
+ "Pupil Labs (Neon)": ["plCompanionAddress", "plCompanionPort"],
546
543
  "EyeLogic": ["ecSampleRate"],
547
544
  }
548
545
  for tracker in trackerParams:
@@ -563,35 +560,54 @@ class SettingsComponent:
563
560
  "false": "disable", # permitted: hide, show, enable, disable
564
561
  }
565
562
  )
563
+ # arrays for eyetracker backends
564
+ backendValues = ["None"]
565
+ backendLabels = ["None"]
566
+ # add known backends from plugins
567
+ for key, cls in knownEyetrackerBackends.items():
568
+ backendValues.append(key)
569
+ backendLabels.append(cls.label or key)
570
+ # add backends via legacy detection method
571
+ try:
572
+ from psychopy.iohub import util as ioUtil
573
+ for legLbl, legKey in ioUtil.getDeviceNames(device_name="eyetracker.hw"):
574
+ if legKey not in backendValues:
575
+ backendValues.append(legKey)
576
+ backendLabels.append(legLbl)
577
+ except:
578
+ # if it doesn't work, just stick with the known backends from plugins
579
+ pass
566
580
 
567
581
  self.params['eyetracker'] = Param(
568
582
  eyetracker, valType='str', inputType="choice",
569
- allowedVals=list(ioDeviceMap),
583
+ allowedVals=backendValues,
584
+ allowedLabels=backendLabels,
570
585
  hint=_translate("What kind of eye tracker should PsychoPy use? Select 'MouseGaze' to use "
571
586
  "the mouse to simulate eye movement (for debugging without a tracker connected)"),
572
587
  label=_translate("Eyetracker device"), categ="Eyetracking"
573
588
  )
574
589
 
575
- #mousegaze
576
- self.params['mgMove'] = Param(
577
- mgMove, valType='str', inputType="choice",
578
- allowedVals=['CONTINUOUS', 'LEFT_BUTTON', 'MIDDLE_BUTTON', 'RIGHT_BUTTON'],
579
- hint=_translate("Mouse button to press for eye movement."),
580
- label=_translate("Move button"), categ="Eyetracking"
581
- )
582
-
583
- self.params['mgBlink'] = Param(
584
- mgBlink, valType='list', inputType="multiChoice",
585
- allowedVals=['LEFT_BUTTON', 'MIDDLE_BUTTON', 'RIGHT_BUTTON'],
586
- hint=_translate("Mouse button to press for a blink."),
587
- label=_translate("Blink button"), categ="Eyetracking"
588
- )
589
-
590
- self.params['mgSaccade'] = Param(
591
- mgSaccade, valType='num', inputType="single",
592
- hint=_translate("Visual degree threshold for Saccade event creation."),
593
- label=_translate("Saccade threshold"), categ="Eyetracking"
594
- )
590
+ # add params from backends
591
+ for backend in knownEyetrackerBackends.values():
592
+ # get params from backend
593
+ params, order = backend.getParams()
594
+ # append order
595
+ self.order += order
596
+ # iterate through params from this backend
597
+ for paramName, param in params.items():
598
+ # add param
599
+ self.params[paramName] = param
600
+ # add dependency on eyetracker param
601
+ self.depends.append({
602
+ 'dependsOn': "eyetracker", # if...
603
+ 'condition': f"== '{backend.key}'", # meets...
604
+ 'param': paramName, # then...
605
+ 'true': "show", # should...
606
+ 'false': "hide", # otherwise...
607
+ })
608
+
609
+ # as users with old versions of the plugin won't have params added dynamically, add legacy
610
+ # params here manually
595
611
 
596
612
  # gazepoint
597
613
  self.params['gpAddress'] = Param(
@@ -613,27 +629,23 @@ class SettingsComponent:
613
629
  hint=_translate("Eye tracker model."),
614
630
  label=_translate("Model name"), categ="Eyetracking"
615
631
  )
616
-
617
632
  self.params['elSimMode'] = Param(
618
633
  elSimMode, valType='bool', inputType="bool",
619
634
  hint=_translate("Set the EyeLink to run in mouse simulation mode."),
620
635
  label=_translate("Mouse simulation mode"), categ="Eyetracking"
621
636
  )
622
-
623
637
  self.params['elSampleRate'] = Param(
624
638
  elSampleRate, valType='num', inputType="choice",
625
639
  allowedVals=['250', '500', '1000', '2000'],
626
640
  hint=_translate("Eye tracker sampling rate."),
627
641
  label=_translate("Sampling rate"), categ="Eyetracking"
628
642
  )
629
-
630
643
  self.params['elTrackEyes'] = Param(
631
644
  elTrackEyes, valType='str', inputType="choice",
632
645
  allowedVals=['LEFT_EYE', 'RIGHT_EYE', 'BOTH'],
633
646
  hint=_translate("Select with eye(s) to track."),
634
647
  label=_translate("Track eyes"), categ="Eyetracking"
635
648
  )
636
-
637
649
  self.params['elLiveFiltering'] = Param(
638
650
  elLiveFiltering, valType='str', inputType="choice",
639
651
  allowedVals=['FILTER_LEVEL_OFF', 'FILTER_LEVEL_1', 'FILTER_LEVEL_2'],
@@ -641,7 +653,6 @@ class SettingsComponent:
641
653
  "This may reduce the sampling speed."),
642
654
  label=_translate("Live sample filtering"), categ="Eyetracking"
643
655
  )
644
-
645
656
  self.params['elDataFiltering'] = Param(
646
657
  elDataFiltering, valType='str', inputType="choice",
647
658
  allowedVals=['FILTER_LEVEL_OFF', 'FILTER_LEVEL_1', 'FILTER_LEVEL_2'],
@@ -649,28 +660,24 @@ class SettingsComponent:
649
660
  "not affect the sampling speed."),
650
661
  label=_translate("Saved sample filtering"), categ="Eyetracking"
651
662
  )
652
-
653
663
  self.params['elTrackingMode'] = Param(
654
664
  elTrackingMode, valType='str', inputType="choice",
655
665
  allowedVals=['PUPIL_CR_TRACKING', 'PUPIL_ONLY_TRACKING'],
656
666
  hint=_translate("Track Pupil-CR or Pupil only."),
657
667
  label=_translate("Pupil tracking mode"), categ="Eyetracking"
658
668
  )
659
-
660
669
  self.params['elPupilAlgorithm'] = Param(
661
670
  elPupilAlgorithm, valType='str', inputType="choice",
662
671
  allowedVals=['ELLIPSE_FIT', 'CENTROID_FIT'],
663
672
  hint=_translate("Algorithm used to detect the pupil center."),
664
673
  label=_translate("Pupil center algorithm"), categ="Eyetracking"
665
674
  )
666
-
667
675
  self.params['elPupilMeasure'] = Param(
668
676
  elPupilMeasure, valType='str', inputType="choice",
669
677
  allowedVals=['PUPIL_AREA', 'PUPIL_DIAMETER', 'NEITHER'],
670
678
  hint=_translate("Type of pupil data to record."),
671
679
  label=_translate("Pupil data type"), categ="Eyetracking"
672
680
  )
673
-
674
681
  self.params['elAddress'] = Param(
675
682
  elAddress, valType='str', inputType="single",
676
683
  hint=_translate("IP Address of the EyeLink *Host* computer."),
@@ -683,19 +690,16 @@ class SettingsComponent:
683
690
  hint=_translate("Eye tracker model."),
684
691
  label=_translate("Model name"), categ="Eyetracking"
685
692
  )
686
-
687
693
  self.params['tbLicenseFile'] = Param(
688
694
  tbLicenseFile, valType='str', inputType="file",
689
695
  hint=_translate("Eye tracker license file (optional)."),
690
696
  label=_translate("License file"), categ="Eyetracking"
691
697
  )
692
-
693
698
  self.params['tbSerialNo'] = Param(
694
699
  tbSerialNo, valType='str', inputType="single",
695
700
  hint=_translate("Eye tracker serial number (optional)."),
696
701
  label=_translate("Serial number"), categ="Eyetracking"
697
702
  )
698
-
699
703
  self.params['tbSampleRate'] = Param(
700
704
  tbSampleRate, valType='num', inputType="single",
701
705
  hint=_translate("Eye tracker sampling rate."),
@@ -734,11 +738,6 @@ class SettingsComponent:
734
738
  hint=_translate("Pupil remote timeout (ms)"),
735
739
  label=_translate("Pupil remote timeout (ms)"), categ="Eyetracking"
736
740
  )
737
- self.params['plPupilCaptureRecordingEnabled'] = Param(
738
- plPupilCaptureRecordingEnabled, valType='bool', inputType="bool",
739
- hint=_translate("Pupil capture recording enabled"),
740
- label=_translate("Pupil capture recording enabled"), categ="Eyetracking"
741
- )
742
741
  self.params['plPupilCaptureRecordingLocation'] = Param(
743
742
  plPupilCaptureRecordingLocation, valType='str', inputType="single",
744
743
  hint=_translate("Pupil capture recording location"),
@@ -754,11 +753,6 @@ class SettingsComponent:
754
753
  hint=_translate("Companion port"),
755
754
  label=_translate("Companion port"), categ="Eyetracking"
756
755
  )
757
- self.params['plCompanionRecordingEnabled'] = Param(
758
- plCompanionRecordingEnabled, valType='bool', inputType="bool",
759
- hint=_translate("Recording enabled"),
760
- label=_translate("Recording enabled"), categ="Eyetracking"
761
- )
762
756
 
763
757
  # EyeLogic
764
758
  self.params['ecSampleRate'] = Param(
@@ -918,17 +912,13 @@ class SettingsComponent:
918
912
  buff.writelines(
919
913
  "prefs.hardware['audioLib'] = {}\n".format(self.params['Audio lib'])
920
914
  )
921
- if self.params['Audio latency priority'].val.lower() != 'use prefs':
922
- buff.writelines(
923
- "prefs.hardware['audioLatencyMode'] = {}\n".format(self.params['Audio latency priority'])
924
- )
925
915
  buff.write(
926
916
  "from psychopy import %s\n" % ', '.join(psychopyImports) +
927
917
  "from psychopy.tools import environmenttools\n"
928
- "from psychopy.constants import (NOT_STARTED, STARTED, PLAYING,"
929
- " PAUSED,\n"
930
- " STOPPED, FINISHED, PRESSED, "
931
- "RELEASED, FOREVER, priority)\n\n"
918
+ "from psychopy.constants import (\n"
919
+ " NOT_STARTED, STARTED, PLAYING, PAUSED, STOPPED, STOPPING, FINISHED, PRESSED, \n"
920
+ " RELEASED, FOREVER, priority\n"
921
+ ")\n\n"
932
922
  "import numpy as np # whole numpy lib is available, "
933
923
  "prepend 'np.'\n"
934
924
  "from numpy import (%s,\n" % ', '.join(_numpyImports[:7]) +
@@ -983,6 +973,9 @@ class SettingsComponent:
983
973
  "# store info about the experiment session\n"
984
974
  "psychopyVersion = '%(version)s'\n"
985
975
  "expName = %(expName)s # from the Builder filename that created this script\n"
976
+ "expVersion = %(expVersion)s\n"
977
+ "# a list of functions to run when the experiment ends (starts off blank)\n"
978
+ "runAtExit = []\n"
986
979
  )
987
980
  buff.writeIndentedLines(code % params)
988
981
  # get info for this experiment
@@ -990,6 +983,7 @@ class SettingsComponent:
990
983
  # add internal expInfo keys
991
984
  expInfo['date|hid'] = "data.getDateStr()"
992
985
  expInfo['expName|hid'] = "expName"
986
+ expInfo['expVersion|hid'] = "expVersion"
993
987
  expInfo['psychopyVersion|hid'] = "psychopyVersion"
994
988
  # construct exp info dict
995
989
  code = (
@@ -1028,6 +1022,14 @@ class SettingsComponent:
1028
1022
  " _winSize = prefs.piloting['forcedWindowSize']\n"
1029
1023
  )
1030
1024
  buff.writeIndented(code % self.params)
1025
+ for key, value in expInfo.items():
1026
+ if key in participantIdAliases:
1027
+ code = (
1028
+ f" # replace default participant ID\n"
1029
+ f" if prefs.piloting['replaceParticipantID']:\n"
1030
+ f" expInfo['{key}'] = 'pilot'\n"
1031
+ )
1032
+ buff.writeIndented(code % self.params)
1031
1033
 
1032
1034
  def prepareResourcesJS(self):
1033
1035
  """Sets up the resources folder and writes the info.php file for PsychoJS
@@ -1154,6 +1156,7 @@ class SettingsComponent:
1154
1156
  code = ("\n// store info about the experiment session:\n"
1155
1157
  "let expName = '%s'; // from the Builder filename that created this script\n"
1156
1158
  "let expInfo = %s;\n"
1159
+ "let PILOTING = util.getUrlParameters().has('__pilotToken');\n"
1157
1160
  "\n" % (jsFilename, expInfoStr))
1158
1161
  buff.writeIndentedLines(code)
1159
1162
 
@@ -1240,7 +1243,7 @@ class SettingsComponent:
1240
1243
 
1241
1244
  # figure out participant id field (if any)
1242
1245
  participantVal = ''
1243
- for target in ('participant', 'Participant', 'Subject', 'Observer'):
1246
+ for target in participantIdAliases:
1244
1247
  if target in self.getInfo(removePipeSyntax=True):
1245
1248
  participantVal = " + expInfo['%s']" % target
1246
1249
  break
@@ -1276,7 +1279,7 @@ class SettingsComponent:
1276
1279
  # set up the ExperimentHandler
1277
1280
  code = ("\n# an ExperimentHandler isn't essential but helps with data saving\n"
1278
1281
  "thisExp = data.ExperimentHandler(\n"
1279
- " name=expName, version='',\n"
1282
+ " name=expName, version=expVersion,\n"
1280
1283
  " extraInfo=expInfo, runtimeInfo=None,\n"
1281
1284
  " originPath=%(originPath)s,\n"
1282
1285
  " savePickle=%(Save psydat file)s, saveWideText=%(Save wide csv file)s,\n"
@@ -1433,7 +1436,6 @@ class SettingsComponent:
1433
1436
  if inits['mgMove'].val == "CONTINUOUS":
1434
1437
  inits['mgMove'].val = "$"
1435
1438
  inits['keyboardBackend'].val = keyboardBackendMap[inits['keyboardBackend'].val]
1436
- inits['eyetracker'].val = ioDeviceMap[inits['eyetracker'].val]
1437
1439
 
1438
1440
  # Make ioConfig dict
1439
1441
  code = (
@@ -1442,244 +1444,234 @@ class SettingsComponent:
1442
1444
  )
1443
1445
  buff.writeIndentedLines(code % inits)
1444
1446
 
1445
- # Add eyetracker config
1447
+ # add eyetracker config
1446
1448
  if self.params['eyetracker'] != "None":
1447
- # Alert user if window is not fullscreen
1448
- if not self.params['Full-screen window'].val:
1449
- alert(code=4540)
1450
- # Alert user if no monitor config
1449
+ # alert user if there's no monitor config
1451
1450
  if self.params['Monitor'].val in ["", None, "None"]:
1452
1451
  alert(code=4545)
1453
- # Alert user if they need calibration and don't have it
1454
- if not self.params['eyetracker'].val in ["MouseGaze", "Pupil Labs (Neon)"]:
1455
- if not any(isinstance(rt, EyetrackerCalibrationRoutine)
1456
- for rt in self.exp.flow):
1457
- alert(code=4510, strFields={"eyetracker": self.params['eyetracker'].val})
1458
-
1459
- # Write code
1452
+ # write opening comment
1460
1453
  code = (
1461
- "\n"
1462
- "# Setup eyetracking\n"
1463
- "ioConfig[%(eyetracker)s] = {\n"
1454
+ "# setup eyetracking\n"
1464
1455
  )
1465
- buff.writeIndentedLines(code % inits)
1466
- buff.setIndentLevel(1, relative=True)
1467
- code = (
1468
- "'name': 'tracker',\n"
1469
- )
1470
- buff.writeIndentedLines(code % inits)
1471
- # Initialise for MouseGaze
1472
- if self.params['eyetracker'] == "MouseGaze":
1473
- code = (
1474
- "'controls': {\n"
1475
- )
1476
- buff.writeIndentedLines(code % inits)
1477
- buff.setIndentLevel(1, relative=True)
1478
- code = (
1479
- "'move': [%(mgMove)s],\n"
1480
- "'blink':%(mgBlink)s,\n"
1481
- "'saccade_threshold': %(mgSaccade)s,\n"
1482
- )
1483
- buff.writeIndentedLines(code % inits)
1484
- buff.setIndentLevel(-1, relative=True)
1485
- code = (
1486
- "}\n"
1487
- )
1488
- buff.writeIndentedLines(code % inits)
1489
-
1490
- elif self.params['eyetracker'] == "GazePoint":
1456
+ buff.writeIndentedLines(code)
1457
+ # if backend is known and has an associated class, use its methods
1458
+ if self.params['eyetracker'].val in knownEyetrackerBackends:
1459
+ # get backend class
1460
+ backend = knownEyetrackerBackends[self.params['eyetracker'].val]
1461
+ # alert user if they need fullscreen and don't have it
1462
+ if backend.needsFullscreen and not self.params['Full-screen window'].val:
1463
+ alert(code=4540)
1464
+ # alert user if they need calibration and don't have it
1465
+ if backend.needsCalibration and not any(
1466
+ isinstance(rt, EyetrackerCalibrationRoutine) for rt in self.exp.flow
1467
+ ):
1468
+ alert(code=4510, strFields={'eyetracker': self.params['eyetracker'].val})
1469
+ # write code
1470
+ backend.writeDeviceCode(inits, buff)
1471
+ # otherwise, do it the old fashioned way
1472
+ else:
1491
1473
  code = (
1492
- "'network_settings': {\n"
1474
+ "ioConfig[%(eyetracker)s] = {\n"
1493
1475
  )
1494
1476
  buff.writeIndentedLines(code % inits)
1495
1477
  buff.setIndentLevel(1, relative=True)
1496
1478
  code = (
1497
- "'ip_address': %(gpAddress)s,\n"
1498
- "'port': %(gpPort)s\n"
1479
+ "'name': 'tracker',\n"
1499
1480
  )
1500
1481
  buff.writeIndentedLines(code % inits)
1501
- buff.setIndentLevel(-1, relative=True)
1502
- code = (
1503
- "}\n"
1504
- )
1505
- buff.writeIndentedLines(code % inits)
1506
-
1507
- elif self.params['eyetracker'] == "Tobii Technology":
1508
- code = (
1509
- "'model_name': %(tbModel)s,\n"
1510
- "'serial_number': %(tbSerialNo)s,\n"
1482
+ # Initialise for MouseGaze
1483
+ if self.params['eyetracker'] == "GazePoint":
1484
+ code = (
1485
+ "'network_settings': {\n"
1486
+ )
1487
+ buff.writeIndentedLines(code % inits)
1488
+ buff.setIndentLevel(1, relative=True)
1489
+ code = (
1490
+ "'ip_address': %(gpAddress)s,\n"
1491
+ "'port': %(gpPort)s\n"
1492
+ )
1493
+ buff.writeIndentedLines(code % inits)
1494
+ buff.setIndentLevel(-1, relative=True)
1495
+ code = (
1496
+ "}\n"
1497
+ )
1498
+ buff.writeIndentedLines(code % inits)
1499
+
1500
+ elif self.params['eyetracker'] == "Tobii Technology":
1501
+ code = (
1502
+ "'model_name': %(tbModel)s,\n"
1503
+ "'serial_number': %(tbSerialNo)s,\n"
1504
+ "'runtime_settings': {\n"
1505
+ )
1506
+ buff.writeIndentedLines(code % inits)
1507
+ buff.setIndentLevel(1, relative=True)
1508
+ code = (
1509
+ "'sampling_rate': %(tbSampleRate)s,\n"
1510
+ )
1511
+ buff.writeIndentedLines(code % inits)
1512
+ buff.setIndentLevel(-1, relative=True)
1513
+ code = (
1514
+ "}\n"
1515
+ )
1516
+ buff.writeIndentedLines(code % inits)
1517
+
1518
+ elif self.params['eyetracker'] == "SR Research Ltd":
1519
+ code = (
1520
+ "'model_name': %(elModel)s,\n"
1521
+ "'simulation_mode': %(elSimMode)s,\n"
1522
+ "'network_settings': %(elAddress)s,\n"
1523
+ "'default_native_data_file_name': 'EXPFILE',\n"
1511
1524
  "'runtime_settings': {\n"
1512
- )
1513
- buff.writeIndentedLines(code % inits)
1514
- buff.setIndentLevel(1, relative=True)
1515
- code = (
1516
- "'sampling_rate': %(tbSampleRate)s,\n"
1517
- )
1518
- buff.writeIndentedLines(code % inits)
1519
- buff.setIndentLevel(-1, relative=True)
1520
- code = (
1521
- "}\n"
1522
- )
1523
- buff.writeIndentedLines(code % inits)
1524
-
1525
- elif self.params['eyetracker'] == "SR Research Ltd":
1526
- code = (
1527
- "'model_name': %(elModel)s,\n"
1528
- "'simulation_mode': %(elSimMode)s,\n"
1529
- "'network_settings': %(elAddress)s,\n"
1530
- "'default_native_data_file_name': 'EXPFILE',\n"
1531
- "'runtime_settings': {\n"
1532
- )
1533
- buff.writeIndentedLines(code % inits)
1534
- buff.setIndentLevel(1, relative=True)
1535
- code = (
1536
- "'sampling_rate': %(elSampleRate)s,\n"
1537
- "'track_eyes': %(elTrackEyes)s,\n"
1538
- "'sample_filtering': {\n"
1539
- )
1540
- buff.writeIndentedLines(code % inits)
1541
- buff.setIndentLevel(1, relative=True)
1542
- code = (
1543
- "'FILTER_FILE': %(elDataFiltering)s,\n"
1544
- "'FILTER_ONLINE': %(elLiveFiltering)s,\n"
1545
- )
1546
- buff.writeIndentedLines(code % inits)
1547
- buff.setIndentLevel(-1, relative=True)
1548
- code = (
1525
+ )
1526
+ buff.writeIndentedLines(code % inits)
1527
+ buff.setIndentLevel(1, relative=True)
1528
+ code = (
1529
+ "'sampling_rate': %(elSampleRate)s,\n"
1530
+ "'track_eyes': %(elTrackEyes)s,\n"
1531
+ "'sample_filtering': {\n"
1532
+ )
1533
+ buff.writeIndentedLines(code % inits)
1534
+ buff.setIndentLevel(1, relative=True)
1535
+ code = (
1536
+ "'FILTER_FILE': %(elDataFiltering)s,\n"
1537
+ "'FILTER_ONLINE': %(elLiveFiltering)s,\n"
1538
+ )
1539
+ buff.writeIndentedLines(code % inits)
1540
+ buff.setIndentLevel(-1, relative=True)
1541
+ code = (
1542
+ "},\n"
1543
+ "'vog_settings': {\n"
1544
+ )
1545
+ buff.writeIndentedLines(code % inits)
1546
+ buff.setIndentLevel(1, relative=True)
1547
+ code = (
1548
+ "'pupil_measure_types': %(elPupilMeasure)s,\n"
1549
+ "'tracking_mode': %(elTrackingMode)s,\n"
1550
+ "'pupil_center_algorithm': %(elPupilAlgorithm)s,\n"
1551
+ )
1552
+ buff.writeIndentedLines(code % inits)
1553
+ buff.setIndentLevel(-1, relative=True)
1554
+ code = (
1555
+ "}\n"
1556
+ )
1557
+ buff.writeIndentedLines(code % inits)
1558
+ buff.setIndentLevel(-1, relative=True)
1559
+ code = (
1560
+ "}\n"
1561
+ )
1562
+ buff.writeIndentedLines(code % inits)
1563
+
1564
+ elif self.params['eyetracker'] == "Pupil Labs":
1565
+ # Open runtime_settings dict
1566
+ code = (
1567
+ "'runtime_settings': {\n"
1568
+ )
1569
+ buff.writeIndentedLines(code % inits)
1570
+ buff.setIndentLevel(1, relative=True)
1571
+
1572
+ # Define runtime_settings dict
1573
+ code = (
1574
+ "'pupillometry_only': %(plPupillometryOnly)s,\n"
1575
+ "'surface_name': %(plSurfaceName)s,\n"
1576
+ "'confidence_threshold': %(plConfidenceThreshold)s,\n"
1577
+ )
1578
+ buff.writeIndentedLines(code % inits)
1579
+
1580
+ # Open runtime_settings > pupil_remote dict
1581
+ code = (
1582
+ "'pupil_remote': {\n"
1583
+ )
1584
+ buff.writeIndentedLines(code % inits)
1585
+ buff.setIndentLevel(1, relative=True)
1586
+
1587
+ # Define runtime_settings > pupil_remote dict
1588
+ code = (
1589
+ "'ip_address': %(plPupilRemoteAddress)s,\n"
1590
+ "'port': %(plPupilRemotePort)s,\n"
1591
+ "'timeout_ms': %(plPupilRemoteTimeoutMs)s,\n"
1592
+ )
1593
+ buff.writeIndentedLines(code % inits)
1594
+
1595
+ # Close runtime_settings > pupil_remote dict
1596
+ buff.setIndentLevel(-1, relative=True)
1597
+ code = (
1549
1598
  "},\n"
1550
- "'vog_settings': {\n"
1551
- )
1552
- buff.writeIndentedLines(code % inits)
1553
- buff.setIndentLevel(1, relative=True)
1554
- code = (
1555
- "'pupil_measure_types': %(elPupilMeasure)s,\n"
1556
- "'tracking_mode': %(elTrackingMode)s,\n"
1557
- "'pupil_center_algorithm': %(elPupilAlgorithm)s,\n"
1558
- )
1559
- buff.writeIndentedLines(code % inits)
1560
- buff.setIndentLevel(-1, relative=True)
1561
- code = (
1562
- "}\n"
1563
- )
1564
- buff.writeIndentedLines(code % inits)
1565
- buff.setIndentLevel(-1, relative=True)
1566
- code = (
1567
- "}\n"
1568
- )
1569
- buff.writeIndentedLines(code % inits)
1570
-
1571
- elif self.params['eyetracker'] == "Pupil Labs":
1572
- # Open runtime_settings dict
1573
- code = (
1574
- "'runtime_settings': {\n"
1575
- )
1576
- buff.writeIndentedLines(code % inits)
1577
- buff.setIndentLevel(1, relative=True)
1578
-
1579
- # Define runtime_settings dict
1580
- code = (
1581
- "'pupillometry_only': %(plPupillometryOnly)s,\n"
1582
- "'surface_name': %(plSurfaceName)s,\n"
1583
- "'confidence_threshold': %(plConfidenceThreshold)s,\n"
1584
- )
1585
- buff.writeIndentedLines(code % inits)
1586
-
1587
- # Open runtime_settings > pupil_remote dict
1588
- code = (
1589
- "'pupil_remote': {\n"
1590
- )
1591
- buff.writeIndentedLines(code % inits)
1592
- buff.setIndentLevel(1, relative=True)
1593
-
1594
- # Define runtime_settings > pupil_remote dict
1595
- code = (
1596
- "'ip_address': %(plPupilRemoteAddress)s,\n"
1597
- "'port': %(plPupilRemotePort)s,\n"
1598
- "'timeout_ms': %(plPupilRemoteTimeoutMs)s,\n"
1599
- )
1600
- buff.writeIndentedLines(code % inits)
1601
-
1602
- # Close runtime_settings > pupil_remote dict
1603
- buff.setIndentLevel(-1, relative=True)
1604
- code = (
1605
- "},\n"
1606
- )
1607
- buff.writeIndentedLines(code % inits)
1608
-
1609
- # Open runtime_settings > pupil_capture_recording dict
1610
- code = (
1611
- "'pupil_capture_recording': {\n"
1612
- )
1613
- buff.writeIndentedLines(code % inits)
1614
- buff.setIndentLevel(1, relative=True)
1615
-
1616
- # Define runtime_settings > pupil_capture_recording dict
1617
- code = (
1618
- "'enabled': %(plPupilCaptureRecordingEnabled)s,\n"
1619
- "'location': %(plPupilCaptureRecordingLocation)s,\n"
1620
- )
1621
- buff.writeIndentedLines(code % inits)
1622
-
1623
- # Close runtime_settings > pupil_capture_recording dict
1624
- buff.setIndentLevel(-1, relative=True)
1625
- code = (
1626
- "}\n"
1627
- )
1628
- buff.writeIndentedLines(code % inits)
1629
-
1630
- # Close runtime_settings dict
1631
- buff.setIndentLevel(-1, relative=True)
1632
- code = (
1633
- "}\n"
1634
- )
1635
- buff.writeIndentedLines(code % inits)
1636
-
1637
- elif self.params['eyetracker'] == "Pupil Labs (Neon)":
1638
- # Open runtime_settings dict
1639
- code = (
1640
- "'runtime_settings': {\n"
1641
- )
1642
- buff.writeIndentedLines(code % inits)
1643
- buff.setIndentLevel(1, relative=True)
1644
-
1645
- # Define runtime_settings dict
1646
- code = (
1647
- "'companion_address': %(plCompanionAddress)s,\n"
1648
- "'companion_port': %(plCompanionPort)s,\n"
1649
- "'recording_enabled': %(plCompanionRecordingEnabled)s,\n"
1650
- )
1651
- buff.writeIndentedLines(code % inits)
1652
-
1653
- # Close runtime_settings dict
1654
- buff.setIndentLevel(-1, relative=True)
1655
- code = (
1656
- "}\n"
1657
- )
1658
- buff.writeIndentedLines(code % inits)
1659
-
1660
- elif self.params['eyetracker'] == "EyeLogic":
1661
- code = (
1662
- "'runtime_settings': {\n"
1663
- )
1664
- buff.writeIndentedLines(code % inits)
1665
- buff.setIndentLevel(1, relative=True)
1666
- code = (
1667
- "'sampling_rate': %(ecSampleRate)s,\n"
1668
- )
1669
- buff.writeIndentedLines(code % inits)
1599
+ )
1600
+ buff.writeIndentedLines(code % inits)
1601
+
1602
+ # Open runtime_settings > pupil_capture_recording dict
1603
+ code = (
1604
+ "'pupil_capture_recording': {\n"
1605
+ )
1606
+ buff.writeIndentedLines(code % inits)
1607
+ buff.setIndentLevel(1, relative=True)
1608
+
1609
+ # Define runtime_settings > pupil_capture_recording dict
1610
+ code = (
1611
+ "'enabled': %(plPupilCaptureRecordingEnabled)s,\n"
1612
+ "'location': %(plPupilCaptureRecordingLocation)s,\n"
1613
+ )
1614
+ buff.writeIndentedLines(code % inits)
1615
+
1616
+ # Close runtime_settings > pupil_capture_recording dict
1617
+ buff.setIndentLevel(-1, relative=True)
1618
+ code = (
1619
+ "}\n"
1620
+ )
1621
+ buff.writeIndentedLines(code % inits)
1622
+
1623
+ # Close runtime_settings dict
1624
+ buff.setIndentLevel(-1, relative=True)
1625
+ code = (
1626
+ "}\n"
1627
+ )
1628
+ buff.writeIndentedLines(code % inits)
1629
+
1630
+ elif self.params['eyetracker'] == "Pupil Labs (Neon)":
1631
+ # Open runtime_settings dict
1632
+ code = (
1633
+ "'runtime_settings': {\n"
1634
+ )
1635
+ buff.writeIndentedLines(code % inits)
1636
+ buff.setIndentLevel(1, relative=True)
1637
+ # Define runtime_settings dict
1638
+ code = (
1639
+ "'companion_address': %(plCompanionAddress)s,\n"
1640
+ "'companion_port': %(plCompanionPort)s,\n"
1641
+ "'recording_enabled': %(plCompanionRecordingEnabled)s,\n"
1642
+ )
1643
+ buff.writeIndentedLines(code % inits)
1644
+
1645
+ # Close runtime_settings dict
1646
+ buff.setIndentLevel(-1, relative=True)
1647
+ code = (
1648
+ "}\n"
1649
+ )
1650
+ buff.writeIndentedLines(code % inits)
1651
+
1652
+ elif self.params['eyetracker'] == "EyeLogic":
1653
+ code = (
1654
+ "'runtime_settings': {\n"
1655
+ )
1656
+ buff.writeIndentedLines(code % inits)
1657
+ buff.setIndentLevel(1, relative=True)
1658
+ code = (
1659
+ "'sampling_rate': %(ecSampleRate)s,\n"
1660
+ )
1661
+ buff.writeIndentedLines(code % inits)
1662
+ buff.setIndentLevel(-1, relative=True)
1663
+ code = (
1664
+ "}\n"
1665
+ )
1666
+ buff.writeIndentedLines(code % inits)
1667
+
1668
+ # Close ioDevice dict
1670
1669
  buff.setIndentLevel(-1, relative=True)
1671
1670
  code = (
1672
1671
  "}\n"
1673
1672
  )
1674
1673
  buff.writeIndentedLines(code % inits)
1675
1674
 
1676
- # Close ioDevice dict
1677
- buff.setIndentLevel(-1, relative=True)
1678
- code = (
1679
- "}\n"
1680
- )
1681
- buff.writeIndentedLines(code % inits)
1682
-
1683
1675
  # Add keyboard to ioConfig
1684
1676
  if self.params['keyboardBackend'] == 'ioHub':
1685
1677
  code = (
@@ -1920,11 +1912,15 @@ class SettingsComponent:
1920
1912
  )
1921
1913
  buff.writeIndentedLines(code)
1922
1914
 
1923
- # show/hide pilot indicator
1915
+ # post-init window adjustments for piloting mode
1924
1916
  code = (
1925
- "# show a visual indicator if we're in piloting mode\n"
1926
- "if PILOTING and prefs.piloting['showPilotingIndicator']:\n"
1927
- " win.showPilotingIndicator()\n"
1917
+ "if PILOTING:\n"
1918
+ " # show a visual indicator if we're in piloting mode\n"
1919
+ " if prefs.piloting['showPilotingIndicator']:\n"
1920
+ " win.showPilotingIndicator()\n"
1921
+ " # always show the mouse in piloting mode\n"
1922
+ " if prefs.piloting['forceMouseVisible']:\n"
1923
+ " win.mouseVisible = True\n"
1928
1924
  )
1929
1925
  buff.writeIndentedLines(code)
1930
1926
 
@@ -2009,9 +2005,9 @@ class SettingsComponent:
2009
2005
  buff.writeIndentedLines(code)
2010
2006
 
2011
2007
  def writePauseCode(self, buff):
2012
- # Open function def
2008
+ # open function def for pause
2013
2009
  code = (
2014
- 'def pauseExperiment(thisExp, win=None, timers=[], playbackComponents=[]):\n'
2010
+ 'def pauseExperiment(thisExp, win=None, timers=[], currentRoutine=None):\n'
2015
2011
  ' """\n'
2016
2012
  ' Pause this experiment, preventing the flow from advancing to the next routine until resumed.\n'
2017
2013
  ' \n'
@@ -2024,9 +2020,9 @@ class SettingsComponent:
2024
2020
  ' Window for this experiment.\n'
2025
2021
  ' timers : list, tuple\n'
2026
2022
  ' List of timers to reset once pausing is finished.\n'
2027
- ' playbackComponents : list, tuple\n'
2028
- ' List of any components with a `pause` method which need to be paused.\n'
2029
- ' """'
2023
+ ' currentRoutine : psychopy.data.Routine\n'
2024
+ ' Current Routine we are in at time of pausing, if any. This object tells PsychoPy what Components to pause/play/dispatch.\n'
2025
+ ' """\n'
2030
2026
  )
2031
2027
  buff.writeIndentedLines(code)
2032
2028
  buff.setIndentLevel(+1, relative=True)
@@ -2040,8 +2036,9 @@ class SettingsComponent:
2040
2036
  "# start a timer to figure out how long we're paused for\n"
2041
2037
  "pauseTimer = core.Clock()\n"
2042
2038
  "# pause any playback components\n"
2043
- "for comp in playbackComponents:\n"
2044
- " comp.pause()\n"
2039
+ "if currentRoutine is not None:\n"
2040
+ " for comp in currentRoutine.getPlaybackComponents():\n"
2041
+ " comp.pause()\n"
2045
2042
  "# make sure we have a keyboard\n"
2046
2043
  "defaultKeyboard = deviceManager.getDevice('defaultKeyboard')\n"
2047
2044
  "if defaultKeyboard is None:\n"
@@ -2060,21 +2057,25 @@ class SettingsComponent:
2060
2057
  " endExperiment(thisExp, win=win)\n"
2061
2058
  )
2062
2059
  code += (
2060
+ " # dispatch messages on response components\n"
2061
+ " if currentRoutine is not None:\n"
2062
+ " for comp in currentRoutine.getDispatchComponents():\n"
2063
+ " comp.device.dispatchMessages()\n"
2063
2064
  " # sleep 1ms so other threads can execute\n"
2064
2065
  " clock.time.sleep(0.001)\n"
2065
2066
  "# if stop was requested while paused, quit\n"
2066
2067
  "if thisExp.status == FINISHED:\n"
2067
2068
  " endExperiment(thisExp, win=win)\n"
2068
2069
  "# resume any playback components\n"
2069
- "for comp in playbackComponents:\n"
2070
- " comp.play()\n"
2070
+ "if currentRoutine is not None:\n"
2071
+ " for comp in currentRoutine.getPlaybackComponents():\n"
2072
+ " comp.play()\n"
2071
2073
  "# reset any timers\n"
2072
2074
  "for timer in timers:\n"
2073
2075
  " timer.addTime(-pauseTimer.getTime())\n"
2074
2076
  )
2075
2077
  buff.writeIndentedLines(code % self.params)
2076
-
2077
- # Exit function def
2078
+ # exit function def
2078
2079
  buff.setIndentLevel(-1, relative=True)
2079
2080
  buff.writeIndentedLines("\n")
2080
2081
 
@@ -2113,6 +2114,9 @@ class SettingsComponent:
2113
2114
  "logging.console.setLevel(logging.WARNING)\n"
2114
2115
  "# mark experiment handler as finished\n"
2115
2116
  "thisExp.status = FINISHED\n"
2117
+ "# run any 'at exit' functions\n"
2118
+ "for fcn in runAtExit:\n"
2119
+ " fcn()\n"
2116
2120
  )
2117
2121
  if self.params['Save log file'].val:
2118
2122
  code += (