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
@@ -1,692 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
- # Part of the PsychoPy library
4
- # Copyright (C) 2012-2020 iSolver Software Solutions (C) 2021 Open Science Tools Ltd.
5
- # Distributed under the terms of the GNU General Public License (GPL).
6
-
7
- import numbers # numbers.Integral is like (int, long) but supports Py3
8
- import os
9
- from collections import namedtuple
10
- import json
11
- import numpy
12
-
13
- from ..errors import print2err
14
-
15
- from pkg_resources import parse_version
16
- import tables
17
-
18
- if parse_version(tables.__version__) < parse_version('3'):
19
- from tables import openFile as open_file
20
-
21
- walk_groups = "walkGroups"
22
- list_nodes = "listNodes"
23
- get_node = "getNode"
24
- read_where = "readWhere"
25
- else:
26
- from tables import open_file
27
-
28
- walk_groups = "walk_groups"
29
- list_nodes = "list_nodes"
30
- get_node = "get_node"
31
- read_where = "read_where"
32
-
33
- _hubFiles = []
34
-
35
-
36
- def openHubFile(filepath, filename, mode):
37
- """
38
- Open an HDF5 DataStore file and register it so that it is closed even on interpreter crash.
39
- """
40
- global _hubFiles
41
- hubFile = open_file(os.path.join(filepath, filename), mode)
42
- _hubFiles.append(hubFile)
43
- return hubFile
44
-
45
-
46
- def displayDataFileSelectionDialog(starting_dir=None):
47
- """Shows a FileDialog and lets you select a .hdf5 file to open for
48
- processing."""
49
- from psychopy.gui.qtgui import fileOpenDlg
50
-
51
- filePath = fileOpenDlg(tryFilePath=starting_dir,
52
- prompt="Select a ioHub HDF5 File",
53
- allowed='HDF5 Files (*.hdf5)')
54
-
55
- if filePath is None:
56
- return None
57
-
58
- return filePath
59
-
60
-
61
- def displayEventTableSelectionDialog(title, list_label, list_values, default=u'Select'):
62
- from psychopy import gui
63
- if default not in list_values:
64
- list_values.insert(0, default)
65
- else:
66
- list_values.remove(list_values)
67
- list_values.insert(0, default)
68
-
69
- selection_dict = {list_label: list_values}
70
- dlg_info = dict(selection_dict)
71
- infoDlg = gui.DlgFromDict(dictionary=dlg_info, title=title)
72
- if not infoDlg.OK:
73
- return None
74
-
75
- while list(dlg_info.values())[0] == default and infoDlg.OK:
76
- dlg_info = dict(selection_dict)
77
- infoDlg = gui.DlgFromDict(dictionary=dlg_info, title=title)
78
-
79
- if not infoDlg.OK:
80
- return None
81
-
82
- return list(dlg_info.values())[0]
83
-
84
-
85
- def saveEventReport(hdf5FilePath="", eventType="", eventFields=[], trialStartMessage=None, trialStopMessage=None,
86
- timeMargins=(0.0, 0.0)):
87
- """
88
- Save a tab delimited event report, optionally splitting events into (trial) groups.
89
-
90
- :param hdf5FilePath:
91
- :param eventType:
92
- :param eventFields:
93
- :param trialStartMessage:
94
- :param trialStopMessage:
95
- :param timeMargins:
96
- :return:
97
- """
98
- # Select the hdf5 file to process.
99
- if not hdf5FilePath:
100
- selectedFilePath = displayDataFileSelectionDialog(os.getcwd())
101
- if selectedFilePath:
102
- hdf5FilePath = selectedFilePath[0]
103
- if not hdf5FilePath:
104
- print("Warning: saveEventReport requires hdf5FilePath. No report saved.")
105
- return None
106
-
107
- dpath, dfile = os.path.split(hdf5FilePath)
108
- datafile = ExperimentDataAccessUtility(dpath, dfile)
109
-
110
- if not eventType:
111
- # Get a dict of all event types -> DataStore table info for the selected DataStore file.
112
- eventTableMappings = datafile.getEventMappingInformation()
113
- # Get event tables that have data...
114
- events_with_data = datafile.getEventsByType()
115
-
116
- # Select which event table to output
117
- eventNameList = []
118
- for event_id in list(events_with_data.keys()):
119
- eventNameList.append(eventTableMappings[event_id].class_name.decode('utf-8'))
120
- eventType = displayEventTableSelectionDialog("Select Event Type to Save", "Event Type:", eventNameList)
121
- if eventType is None:
122
- print("Warning: saveEventReport requires eventType. No report saved.")
123
- datafile.close()
124
- return None
125
-
126
- trial_times = []
127
- if trialStartMessage and trialStopMessage:
128
- # Create a table of trial_index, trial_start_time, trial_end_time for each trial by
129
- # getting the time of 'TRIAL_START' and 'TRIAL_END' experiment messages.
130
- mgs_table = datafile.getEventTable('MessageEvent')
131
- trial_start_msgs = mgs_table.where('text == b"%s"' % trialStartMessage)
132
- for mix, msg in enumerate(trial_start_msgs):
133
- trial_times.append([mix + 1, msg['time'] - timeMargins[0], 0])
134
- trial_end_msgs = mgs_table.where('text == b"%s"' % trialStopMessage)
135
- for mix, msg in enumerate(trial_end_msgs):
136
- trial_times[mix][2] = msg['time'] + timeMargins[1]
137
- del mgs_table
138
- elif trialStartMessage is None and trialStopMessage is None:
139
- # do not split events into trial groupings
140
- pass
141
- else:
142
- print("Warning: saveEventReport requires trialStartMessage and trialStopMessage to be strings or both None."
143
- " No report saved.")
144
- datafile.close()
145
- return None
146
-
147
- # Get the event table to generate report for
148
- event_table = datafile.getEventTable(eventType)
149
-
150
- if not eventFields:
151
- # If no event fields were specified, report (almost) all event fields.
152
- eventFields = [c for c in event_table.colnames if c not in ['experiment_id', 'session_id', 'device_id',
153
- 'type', 'filter_id']]
154
-
155
- if eventType == 'MessageEvent':
156
- # Sort experiment messages by time since they may not be ordered chronologically.
157
- event_table = event_table.read()
158
- event_table.sort(order='time')
159
-
160
- ecount = 0
161
- # Open a file to save the tab delimited output to.
162
- output_file_name = os.path.join(dpath, "%s.%s.txt" % (dfile[:-5], eventType))
163
- with open(output_file_name, 'w') as output_file:
164
- # Save header row to file
165
- if trial_times:
166
- column_names = ['TRIAL_INDEX', trialStartMessage, trialStopMessage] + eventFields
167
- else:
168
- column_names = eventFields
169
-
170
- output_file.write('\t'.join(column_names))
171
- output_file.write('\n')
172
-
173
- event_groupings = []
174
- if trial_times:
175
- # Split events into trials
176
- for tindex, tstart, tstop in trial_times:
177
- if eventType == 'MessageEvent':
178
- event_groupings.append(event_table[(event_table['time'] >= tstart) & (event_table['time']
179
- <= tstop)])
180
- else:
181
- event_groupings.append(event_table.where("(time >= %f) & (time <= %f)" % (tstart, tstop)))
182
- else:
183
- # Report events without splitting them into trials
184
- if eventType == 'MessageEvent':
185
- event_groupings.append(event_table)
186
- else:
187
- event_groupings.append(event_table.iterrows())
188
-
189
- # Save a row for each event within the trial period
190
- for tid, trial_events in enumerate(event_groupings):
191
- for event in trial_events:
192
- event_data = []
193
- for c in eventFields:
194
- cv = event[c]
195
- if type(cv) == numpy.bytes_:
196
- cv = event[c].decode('utf-8')
197
- if type(cv) == str and len(cv) == 0:
198
- cv = '.'
199
- event_data.append(str(cv))
200
- if trial_times:
201
- tindex, tstart, tstop = trial_times[tid]
202
- output_file.write('\t'.join([str(tindex), str(tstart), str(tstop)] + event_data))
203
- else:
204
- output_file.write('\t'.join(event_data))
205
- output_file.write('\n')
206
- ecount += 1
207
-
208
- # Done report creation, close input file
209
- datafile.close()
210
- return output_file_name, ecount
211
-
212
-
213
- ########### Experiment / Experiment Session Based Data Access #################
214
-
215
-
216
- class ExperimentDataAccessUtility:
217
- """The ExperimentDataAccessUtility provides a simple, high level, way to
218
- access data saved in an ioHub DataStore HDF5 file. Data access is done by
219
- providing information at an experiment and session level, as well as
220
- specifying the ioHub Event types you want to retrieve data for.
221
-
222
- An instance of the ExperimentDataAccessUtility class is created by providing
223
- the location and name of the file to read, as well as any session code
224
- filtering you want applied to the retrieved datasets.
225
-
226
- Args:
227
- hdfFilePath (str): The path of the directory the DataStore HDF5 file is in.
228
-
229
- hdfFileName (str): The name of the DataStore HDF5 file.
230
-
231
- experimentCode (str): If multi-experiment support is enabled for the DataStore file, this argument can be used to specify what experiment data to load based on the experiment_code given. NOTE: Multi-experiment data file support is not well tested and should not be used at this point.
232
-
233
- sessionCodes (str or list): The experiment session code to filter data by. If a list of codes is given, then all codes in the list will be used.
234
-
235
- Returns:
236
- object: the created instance of the ExperimentDataAccessUtility, ready to get your data!
237
-
238
- """
239
-
240
- def __init__(self, hdfFilePath, hdfFileName, experimentCode=None, sessionCodes=[], mode='r'):
241
- """An instance of the ExperimentDataAccessUtility class is created by
242
- providing the location and name of the file to read, as well as any
243
- session code filtering you want applied to the retrieved datasets.
244
-
245
- Args:
246
- hdfFilePath (str): The path of the directory the DataStore HDF5 file is in.
247
-
248
- hdfFileName (str): The name of the DataStore HDF5 file.
249
-
250
- experimentCode (str): If multi-experiment support is enabled for the DataStore file, this argument can be used to specify what experiment data to load based on the experiment_code given. NOTE: Multi-experiment data file support is not well tested and should not be used at this point.
251
-
252
- sessionCodes (str or list): The experiment session code to filter data by. If a list of codes is given, then all codes in the list will be used.
253
-
254
- Returns:
255
- object: the created instance of the ExperimentDataAccessUtility, ready to get your data!
256
-
257
- """
258
- self.hdfFilePath = hdfFilePath
259
- self.hdfFileName = hdfFileName
260
- self.mode = mode
261
- self.hdfFile = None
262
-
263
- self._experimentCode = experimentCode
264
- self._sessionCodes = sessionCodes
265
- self._lastWhereClause = None
266
-
267
- try:
268
- self.hdfFile = openHubFile(hdfFilePath, hdfFileName, mode)
269
- except Exception as e:
270
- raise ExperimentDataAccessException(e)
271
-
272
- self.getExperimentMetaData()
273
-
274
- def printTableStructure(self, tableName):
275
- """Print to stdout the current structure and content statistics of the
276
- specified DataStore table. To print out the complete structure of the
277
- DataStore file, including the name of all available tables, see the
278
- printHubFileStructure method.
279
-
280
- Args:
281
- tableName (str): The DataStore table name to print metadata information out for.
282
-
283
- """
284
- if self.hdfFile:
285
- hubFile = self.hdfFile
286
- for group in getattr(hubFile, walk_groups)("/"):
287
- for table in getattr(hubFile, list_nodes)(group, classname='Table'):
288
- if table.name == tableName:
289
- print('------------------')
290
- print('Path:', table)
291
- print('Table name:', table.name)
292
- print('Number of rows in table:', table.nrows)
293
- print('Number of cols in table:', len(table.colnames))
294
- print('Attribute name := type, shape:')
295
- for name in table.colnames:
296
- print('\t', name, ':= %s, %s' % (table.coldtypes[name], table.coldtypes[name].shape))
297
- print('------------------')
298
- return
299
-
300
- def printHubFileStructure(self):
301
- """Print to stdout the current global structure of the loaded DataStore
302
- File."""
303
- if self.hdfFile:
304
- print(self.hdfFile)
305
-
306
- def getExperimentMetaData(self):
307
- """Returns the the metadata for the experiment the datStore file is
308
- for.
309
-
310
- **Docstr TBC.**
311
-
312
- """
313
- if self.hdfFile:
314
- expcols = self.hdfFile.root.data_collection.experiment_meta_data.colnames
315
- if 'sessions' not in expcols:
316
- expcols.append('sessions')
317
- ExperimentMetaDataInstance = namedtuple(
318
- 'ExperimentMetaDataInstance', expcols)
319
- experiments = []
320
- for e in self.hdfFile.root.data_collection.experiment_meta_data:
321
- self._experimentID = e['experiment_id']
322
- a_exp = list(e[:])
323
- a_exp.append(self.getSessionMetaData())
324
- experiments.append(ExperimentMetaDataInstance(*a_exp))
325
- return experiments
326
-
327
- def getSessionMetaData(self, sessions=None):
328
- """
329
- Returns the the metadata associated with the experiment session codes in use.
330
-
331
- **Docstr TBC.**
332
-
333
- """
334
- if self.hdfFile:
335
- if sessions is None:
336
- sessions = []
337
-
338
- sessionCodes = self._sessionCodes
339
- sesscols = self.hdfFile.root.data_collection.session_meta_data.colnames
340
- SessionMetaDataInstance = namedtuple('SessionMetaDataInstance', sesscols)
341
- for r in self.hdfFile.root.data_collection.session_meta_data:
342
- if (len(sessionCodes) == 0 or r['code'] in sessionCodes) and r['experiment_id'] == self._experimentID:
343
- rcpy = list(r[:])
344
- rcpy[-1] = json.loads(rcpy[-1])
345
- sessions.append(SessionMetaDataInstance(*rcpy))
346
- return sessions
347
-
348
- def getTableForPath(self, path):
349
- """
350
- Given a valid table path within the DataStore file, return the accociated table.
351
- """
352
- getattr(self.hdfFile, get_node)(path)
353
-
354
- def getEventTable(self, event_type):
355
- """
356
- Returns the DataStore table that contains events of the specified type.
357
-
358
- **Docstr TBC.**
359
-
360
- """
361
- if self.hdfFile:
362
- klassTables = self.hdfFile.root.class_table_mapping
363
- event_column = None
364
- event_value = None
365
-
366
- if isinstance(event_type, str):
367
- if event_type.find('Event') >= 0:
368
- event_column = 'class_name'
369
- event_value = event_type
370
- else:
371
- event_value = ''
372
- tokens = event_type.split('_')
373
- for t in tokens:
374
- event_value += t[0].upper() + t[1:].lower()
375
- event_value = event_type + 'Event'
376
- elif isinstance(event_type, numbers.Integral):
377
- event_column = 'class_id'
378
- event_value = event_type
379
- else:
380
- <<<<<<< HEAD
381
- print2err('getEventTable error: event_type arguement must be a string or and int')
382
- =======
383
- print2err(
384
- 'getEventTable error: event_type argument must be a string or and int')
385
- >>>>>>> release
386
- return None
387
-
388
- result = []
389
- where_cls = '(%s == b"%s") & (class_type_id == 1)' % (event_column, event_value)
390
- for row in klassTables.where(where_cls):
391
- result.append(row.fetch_all_fields())
392
-
393
- if len(result) == 0:
394
- return None
395
-
396
- if len(result) != 1:
397
- print2err('event_type_id passed to getEventAttribute can only return one row from CLASS_MAPPINGS.')
398
- return None
399
- tablePathString = result[0][3]
400
- if isinstance(tablePathString, bytes):
401
- tablePathString = tablePathString.decode('utf-8')
402
- return getattr(self.hdfFile, get_node)(tablePathString)
403
- return None
404
-
405
- def getEventMappingInformation(self):
406
- """Returns details on how ioHub Event Types are mapped to tables within
407
- the given DataStore file."""
408
- if self.hdfFile:
409
- eventMappings = dict()
410
- class_2_table = self.hdfFile.root.class_table_mapping
411
- EventTableMapping = namedtuple(
412
- 'EventTableMapping',
413
- self.hdfFile.root.class_table_mapping.colnames)
414
- for row in class_2_table[:]:
415
- eventMappings[row['class_id']] = EventTableMapping(*row)
416
- return eventMappings
417
- return None
418
-
419
- def getEventsByType(self, condition_str=None):
420
- """Returns a dict of all event tables within the DataStore file that
421
- have at least one event instance saved.
422
-
423
- Keys are Event Type constants, as specified by
424
- iohub.EventConstants. Each value is a row iterator for events of
425
- that type.
426
-
427
- """
428
- eventTableMappings = self.getEventMappingInformation()
429
- if eventTableMappings:
430
- events_by_type = dict()
431
- getNode = getattr(self.hdfFile, get_node)
432
- for event_type_id, event_mapping_info in eventTableMappings.items():
433
- try:
434
- cond = '(type == %d)' % (event_type_id)
435
- if condition_str:
436
- cond += ' & ' + condition_str
437
- et_path = event_mapping_info.table_path
438
- if isinstance(et_path, bytes):
439
- et_path = et_path.decode('utf-8')
440
- events_by_type[event_type_id] = next(getNode(et_path).where(cond))
441
- except StopIteration:
442
- pass
443
- return events_by_type
444
- return None
445
-
446
- def getConditionVariablesTable(self):
447
- """
448
- **Docstr TBC.**
449
- """
450
- cv_group = self.hdfFile.root.data_collection.condition_variables
451
- ecv = 'EXP_CV_%d' % (self._experimentID,)
452
- if ecv in cv_group._v_leaves:
453
- return cv_group._v_leaves[ecv]
454
- return None
455
-
456
- def getConditionVariableNames(self):
457
- """
458
- **Docstr TBC.**
459
- """
460
- cv_group = self.hdfFile.root.data_collection.condition_variables
461
- ecv = "EXP_CV_%d" % (self._experimentID,)
462
- if ecv in cv_group._v_leaves:
463
- ecvTable = cv_group._v_leaves[ecv]
464
- return ecvTable.colnames
465
- return None
466
-
467
- def getConditionVariables(self, filter=None):
468
- """
469
- **Docstr TBC.**
470
- """
471
- if filter is None:
472
- session_ids = []
473
- for s in self.getExperimentMetaData()[0].sessions:
474
- session_ids.append(s.session_id)
475
- filter = dict(SESSION_ID=(' in ', session_ids))
476
-
477
- ConditionSetInstance = None
478
-
479
- for conditionVarName, conditionVarComparitor in filter.items():
480
- avComparison, value = conditionVarComparitor
481
-
482
- cv_group = self.hdfFile.root.data_collection.condition_variables
483
- cvrows = []
484
- ecv = "EXP_CV_%d" % (self._experimentID,)
485
- if ecv in cv_group._v_leaves:
486
- ecvTable = cv_group._v_leaves[ecv]
487
-
488
- if ConditionSetInstance is None:
489
- colnam = ecvTable.colnames
490
- ConditionSetInstance = namedtuple('ConditionSetInstance', colnam)
491
-
492
- cvrows.extend(
493
- [
494
- ConditionSetInstance(
495
- *
496
- r[:]) for r in ecvTable if all(
497
- [
498
- eval(
499
- '{0} {1} {2}'.format(
500
- r[conditionVarName],
501
- conditionVarComparitor[0],
502
- conditionVarComparitor[1])) for conditionVarName,
503
- conditionVarComparitor in filter.items()])])
504
- return cvrows
505
-
506
- def getValuesForVariables(self, cv, value, cvNames):
507
- """
508
- **Docstr TBC.**
509
- """
510
- if isinstance(value, (list, tuple)):
511
- resolvedValues = []
512
- for v in value:
513
- if isinstance(value, str) and value.startswith('@') and value.endswith('@'):
514
- value = value[1:-1]
515
- if value in cvNames:
516
- resolvedValues.append(getattr(cv, v))
517
- else:
518
- raise ExperimentDataAccessException('getEventAttributeValues: {0} is not a valid attribute '
519
- 'name in {1}'.format(v, cvNames))
520
- elif isinstance(value, str):
521
- resolvedValues.append(value)
522
- return resolvedValues
523
- elif isinstance(value, str) and value.startswith('@') and value.endswith('@'):
524
- value = value[1:-1]
525
- if value in cvNames:
526
- return getattr(cv, value)
527
- else:
528
- raise ExperimentDataAccessException('getEventAttributeValues: {0} is not a valid attribute name'
529
- ' in {1}'.format(value, cvNames))
530
- else:
531
- raise ExperimentDataAccessException('Unhandled value type !: {0} is not a valid type for value '
532
- '{1}'.format(type(value), value))
533
-
534
- def getEventAttributeValues(self, event_type_id, event_attribute_names, filter_id=None,
535
- conditionVariablesFilter=None, startConditions=None, endConditions=None):
536
- """
537
- **Docstr TBC.**
538
-
539
- Args:
540
- event_type_id
541
- event_attribute_names
542
- filter_id
543
- conditionVariablesFilter
544
- startConditions
545
- endConditions
546
-
547
- Returns:
548
- Values for the specified event type and event attribute columns which match the provided experiment
549
- condition variable filter, starting condition filer, and ending condition filter criteria.
550
- """
551
- if self.hdfFile:
552
- klassTables = self.hdfFile.root.class_table_mapping
553
-
554
- deviceEventTable = None
555
-
556
- result = [row.fetch_all_fields() for row in klassTables.where('(class_id == %d) &'
557
- ' (class_type_id == 1)' % (event_type_id))]
558
- if len(result) != 1:
559
- raise ExperimentDataAccessException("event_type_id returned > 1 row from CLASS_MAPPINGS.")
560
- tablePathString = result[0][3]
561
- if isinstance(tablePathString, bytes):
562
- tablePathString = tablePathString.decode('utf-8')
563
- deviceEventTable = getattr(self.hdfFile, get_node)(tablePathString)
564
-
565
- for ename in event_attribute_names:
566
- if ename not in deviceEventTable.colnames:
567
- raise ExperimentDataAccessException('getEventAttribute: %s does not have a column named %s' %
568
- (deviceEventTable.title, event_attribute_names))
569
-
570
- resultSetList = []
571
-
572
- csier = list(event_attribute_names)
573
- csier.append('query_string')
574
- csier.append('condition_set')
575
- EventAttributeResults = namedtuple('EventAttributeResults', csier)
576
-
577
- if deviceEventTable is not None:
578
- if not isinstance(event_attribute_names, (list, tuple)):
579
- event_attribute_names = [event_attribute_names, ]
580
-
581
- filteredConditionVariableList = None
582
- if conditionVariablesFilter is None:
583
- filteredConditionVariableList = self.getConditionVariables()
584
- else:
585
- filteredConditionVariableList = self.getConditionVariables(conditionVariablesFilter)
586
-
587
- cvNames = self.getConditionVariableNames()
588
-
589
- # no further where clause building needed; get reseults and
590
- # return
591
- if startConditions is None and endConditions is None:
592
- for cv in filteredConditionVariableList:
593
-
594
- wclause = '( experiment_id == {0} ) & ( SESSION_ID == {1} )'.format(self._experimentID,
595
- cv.SESSION_ID)
596
-
597
- wclause += ' & ( type == {0} ) '.format(event_type_id)
598
-
599
- if filter_id is not None:
600
- wclause += '& ( filter_id == {0} ) '.format(filter_id)
601
-
602
- resultSetList.append([])
603
-
604
- for ename in event_attribute_names:
605
- resultSetList[-1].append(getattr(deviceEventTable, read_where)(wclause, field=ename))
606
- resultSetList[-1].append(wclause)
607
- resultSetList[-1].append(cv)
608
-
609
- eventAttributeResults = EventAttributeResults(*resultSetList[-1])
610
- resultSetList[-1] = eventAttributeResults
611
-
612
- return resultSetList
613
-
614
- # start or end conditions exist....
615
- for cv in filteredConditionVariableList:
616
- resultSetList.append([])
617
-
618
- wclause = '( experiment_id == {0} ) & ( session_id == {1} )'.format(self._experimentID,
619
- cv.SESSION_ID)
620
-
621
- wclause += ' & ( type == {0} ) '.format(event_type_id)
622
-
623
- if filter_id is not None:
624
- wclause += '& ( filter_id == {0} ) '.format(filter_id)
625
-
626
- # start Conditions need to be added to where clause
627
- if startConditions is not None:
628
- wclause += '& ('
629
- for conditionAttributeName, conditionAttributeComparitor in startConditions.items():
630
- avComparison, value = conditionAttributeComparitor
631
- value = self.getValuesForVariables(cv, value, cvNames)
632
- wclause += ' ( {0} {1} {2} ) & '.format(conditionAttributeName, avComparison, value)
633
- wclause = wclause[:-3]
634
- wclause += ' ) '
635
-
636
- # end Conditions need to be added to where clause
637
- if endConditions is not None:
638
- wclause += ' & ('
639
- for conditionAttributeName, conditionAttributeComparitor in endConditions.items():
640
- avComparison, value = conditionAttributeComparitor
641
- value = self.getValuesForVariables(cv, value, cvNames)
642
- wclause += ' ( {0} {1} {2} ) & '.format(conditionAttributeName, avComparison, value)
643
- wclause = wclause[:-3]
644
- wclause += ' ) '
645
-
646
- for ename in event_attribute_names:
647
- resultSetList[-1].append(getattr(deviceEventTable, read_where)(wclause, field=ename))
648
- resultSetList[-1].append(wclause)
649
- resultSetList[-1].append(cv)
650
-
651
- eventAttributeResults = EventAttributeResults(*resultSetList[-1])
652
- resultSetList[-1] = eventAttributeResults
653
-
654
- return resultSetList
655
-
656
- return None
657
-
658
- def getEventIterator(self, event_type):
659
- """
660
- **Docstr TBC.**
661
-
662
- Args:
663
- event_type
664
-
665
- Returns:
666
- (iterator): An iterator providing access to each matching event as a numpy recarray.
667
- """
668
- return self.getEventTable(event_type).iterrows()
669
-
670
- def close(self):
671
- """Close the ExperimentDataAccessUtility and associated DataStore
672
- File."""
673
- global _hubFiles
674
- if self.hdfFile in _hubFiles:
675
- _hubFiles.remove(self.hdfFile)
676
- self.hdfFile.close()
677
-
678
- self.experimentCodes = None
679
- self.hdfFilePath = None
680
- self.hdfFileName = None
681
- self.mode = None
682
- self.hdfFile = None
683
-
684
- def __del__(self):
685
- try:
686
- self.close()
687
- except Exception:
688
- pass
689
-
690
-
691
- class ExperimentDataAccessException(Exception):
692
- pass