psychopy 2024.2.1__py3-none-any.whl → 2024.2.4__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (276) hide show
  1. psychopy/.DS_Store +0 -0
  2. psychopy/GIT_SHA +1 -1
  3. psychopy/VERSION +1 -1
  4. psychopy/__init__.py +10 -1
  5. psychopy/__init__.py.orig +65 -0
  6. psychopy/app/{locale/ar_001/.DS_Store → .DS_Store} +0 -0
  7. psychopy/app/Resources/.DS_Store +0 -0
  8. psychopy/app/_psychopyApp.py +11 -3
  9. psychopy/app/appData.spec +1 -1
  10. psychopy/app/builder/builder.py +1 -1
  11. psychopy/app/builder/builder.py.orig +3932 -0
  12. psychopy/app/builder/dialogs/__init__.py.orig +1679 -0
  13. psychopy/app/builder/dialogs/paramCtrls.py +1 -1
  14. psychopy/app/builder/dialogs/paramCtrls.py.orig +713 -0
  15. psychopy/app/colorpicker/__init__.py.orig +411 -0
  16. psychopy/app/cortex.log +0 -0
  17. psychopy/app/jobs.py +8 -1
  18. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +2452 -1731
  19. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.mo +0 -0
  20. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.po +6127 -0
  21. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.mo +0 -0
  22. psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.po +7366 -0
  23. psychopy/app/plugin_manager/dialog.py +9 -7
  24. psychopy/app/ribbon.py +2 -1
  25. psychopy/app/runner/runner.py +7 -5
  26. psychopy/clock.py +8 -4
  27. psychopy/core.py.orig +169 -0
  28. psychopy/demos/builder/Design Templates/randomisedBlocks/html/index.html +23 -0
  29. psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks-legacy-browsers.js +423 -0
  30. psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks.js +427 -0
  31. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/chooseBlock.xlsx +0 -0
  32. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/facesBlock.xlsx +0 -0
  33. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/housesBlock.xlsx +0 -0
  34. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face01.jpg +0 -0
  35. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face02.jpg +0 -0
  36. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face03.jpg +0 -0
  37. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house01.jpg +0 -0
  38. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house02.jpg +0 -0
  39. psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house03.jpg +0 -0
  40. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.py +330 -0
  41. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +330 -0
  42. psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xml +298 -0
  43. psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xsd +120 -0
  44. psychopy/demos/builder/Tools/.DS_Store +0 -0
  45. psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
  46. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +38 -0
  47. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +3418 -0
  48. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
  49. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +2 -0
  50. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +15 -0
  51. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
  52. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.psyexp +323 -0
  53. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.py +562 -0
  54. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +562 -0
  55. psychopy/demos/builder/Tools/gammaCalibration/questStairs.xlsx +0 -0
  56. psychopy/demos/builder/Tools/gammaCalibration/readme.md +0 -0
  57. psychopy/demos/builder/Tools/gammaCalibration/resources/low_contrast.png +0 -0
  58. psychopy/demos/builder/Tools/gammaCalibration/resources/make_2nd_order_tex.py +59 -0
  59. psychopy/demos/builder/Tools/gammaCalibration/resources/second_order_tex.png +0 -0
  60. psychopy/demos/coder/.DS_Store +0 -0
  61. psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
  62. psychopy/demos/coder/iohub/.iohpid +1 -0
  63. psychopy/demos/coder/iohub/eyetracking/.iohpid +1 -0
  64. psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
  65. psychopy/demos/coder/stimuli/.DS_Store +0 -0
  66. psychopy/demos/coder/stimuli/radialGratingContracting.py +29 -0
  67. psychopy/experiment/_experiment.py.orig +1032 -0
  68. psychopy/experiment/components/.DS_Store +0 -0
  69. psychopy/experiment/components/_base.py +13 -4
  70. psychopy/experiment/components/_base.py.orig +823 -0
  71. psychopy/experiment/components/form/.DS_Store +0 -0
  72. psychopy/experiment/components/microphone/__init__.py +10 -1
  73. psychopy/experiment/components/microphone/__init__.py.orig +490 -0
  74. psychopy/experiment/components/polygon/__init__.py +21 -22
  75. psychopy/experiment/components/settings/__init__.py +13 -14
  76. psychopy/experiment/components/settings/__init__.py.orig +1337 -0
  77. psychopy/experiment/components/textbox/__init__.py.orig +310 -0
  78. psychopy/experiment/components/webcam/.DS_Store +0 -0
  79. psychopy/experiment/components/webcam/light/.DS_Store +0 -0
  80. psychopy/experiment/flow.py +10 -8
  81. psychopy/experiment/loops.py.orig +829 -0
  82. psychopy/experiment/params.py +8 -3
  83. psychopy/experiment/params.py.orig +408 -0
  84. psychopy/experiment/routine.py.orig +503 -0
  85. psychopy/experiment/routines/_base.py +15 -6
  86. psychopy/experiment/routines/counterbalance/__init__.py +1 -0
  87. psychopy/gui/qtgui.py +14 -7
  88. psychopy/gui/util.py +10 -14
  89. psychopy/gui/wxgui.py +10 -4
  90. psychopy/hardware/.DS_Store +0 -0
  91. psychopy/hardware/brainproducts.py.orig +680 -0
  92. psychopy/hardware/iolab.py.orig +238 -0
  93. psychopy/hardware/manager.py +1 -1
  94. psychopy/hardware/photodiode.py +59 -27
  95. psychopy/hardware/serialport.py +51 -0
  96. psychopy/hardware/speaker.py +4 -4
  97. psychopy/iohub/datastore/__init__.py.orig +443 -0
  98. psychopy/iohub/datastore/util.py.orig +692 -0
  99. psychopy/iohub/devices/mouse/darwin.py.orig +427 -0
  100. psychopy/iohub/devices/mouse/linux2.py.orig +198 -0
  101. psychopy/preferences/.DS_Store +0 -0
  102. psychopy/projects/pavlovia.py +10 -3
  103. psychopy/projects/pavlovia.py.orig +1295 -0
  104. psychopy/sound/backend_ptb.py +22 -5
  105. psychopy/sound/transcribe.py +24 -4
  106. psychopy/tests/.DS_Store +0 -0
  107. psychopy/tests/data/.DS_Store +0 -0
  108. psychopy/tests/data/TestCircle_fill_local.png +0 -0
  109. psychopy/tests/data/__test.png +0 -0
  110. psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
  111. psychopy/tests/data/aperture1_norm_local.png +0 -0
  112. psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
  113. psychopy/tests/data/beatandrcos_height_local.png +0 -0
  114. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  115. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  116. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  117. psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
  118. psychopy/tests/data/blend_add_height_local.png +0 -0
  119. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  120. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  121. psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
  122. psychopy/tests/data/blend_add_norm_local.png +0 -0
  123. psychopy/tests/data/blend_add_stencil_local.png +0 -0
  124. psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
  125. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  126. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  127. psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
  128. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  129. psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
  130. psychopy/tests/data/circleHex_height_local.png +0 -0
  131. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  132. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  133. psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
  134. psychopy/tests/data/circleHex_norm_local.png +0 -0
  135. psychopy/tests/data/circleHex_stencil_local.png +0 -0
  136. psychopy/tests/data/color_comparison_local.png +0 -0
  137. psychopy/tests/data/corrFullRandom_local.csv +16 -0
  138. psychopy/tests/data/corrFullRandom_local.tsv +6 -0
  139. psychopy/tests/data/correctScript/.DS_Store +0 -0
  140. psychopy/tests/data/dots_height_local.png +0 -0
  141. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  142. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  143. psychopy/tests/data/dots_normNoShade_local.png +0 -0
  144. psychopy/tests/data/dots_norm_local.png +0 -0
  145. psychopy/tests/data/dots_stencil_local.png +0 -0
  146. psychopy/tests/data/elarray1_height_local.png +0 -0
  147. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  148. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  149. psychopy/tests/data/elarray1_norm_local.png +0 -0
  150. psychopy/tests/data/elarray1_stencil_local.png +0 -0
  151. psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
  152. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  153. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  154. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  155. psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
  156. psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
  157. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  158. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  159. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  160. psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
  161. psychopy/tests/data/gabor1_height_local.png +0 -0
  162. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  163. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  164. psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
  165. psychopy/tests/data/gabor1_norm_local.png +0 -0
  166. psychopy/tests/data/gabor1_stencil_local.png +0 -0
  167. psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
  168. psychopy/tests/data/imageAndGauss_height_local.png +0 -0
  169. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  170. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  171. psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
  172. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  173. psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
  174. psychopy/tests/data/movFrame1_stencil_local.png +0 -0
  175. psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
  176. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  177. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  178. psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
  179. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  180. psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
  181. psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
  182. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  183. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  184. psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
  185. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  186. psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
  187. psychopy/tests/data/numpyImage_height_local.png +0 -0
  188. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  189. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  190. psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
  191. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  192. psychopy/tests/data/numpyImage_stencil_local.png +0 -0
  193. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  194. psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
  195. psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
  196. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  197. psychopy/tests/data/shape2_1_stencil_local.png +0 -0
  198. psychopy/tests/data/testLoopsBlocks.psyexp_local.py +328 -0
  199. psychopy/tests/data/text1_height_local.png +0 -0
  200. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  201. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  202. psychopy/tests/data/text1_norm_local.png +0 -0
  203. psychopy/tests/data/text1_stencil_local.png +0 -0
  204. psychopy/tests/data/text2_height.png +0 -0
  205. psychopy/tests/data/text2_normAddBlend.png +0 -0
  206. psychopy/tests/data/text2_normHexbackground.png +0 -0
  207. psychopy/tests/data/text2_stencil.png +0 -0
  208. psychopy/tests/data/wedge1_height_local.png +0 -0
  209. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  210. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  211. psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
  212. psychopy/tests/data/wedge1_norm_local.png +0 -0
  213. psychopy/tests/data/wedge1_stencil_local.png +0 -0
  214. psychopy/tests/test_app/.DS_Store +0 -0
  215. psychopy/tests/test_app/test_builder/.DS_Store +0 -0
  216. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.csv +9 -0
  217. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +177 -0
  218. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
  219. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
  220. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.csv +9 -0
  221. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +168 -0
  222. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
  223. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
  224. psychopy/tests/test_data/.DS_Store +0 -0
  225. psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +68 -0
  226. psychopy/tests/test_tools/test_arraytools.py +112 -0
  227. psychopy/tests/test_visual/test_image.py.orig +219 -0
  228. psychopy/tools/arraytools.py +47 -0
  229. psychopy/tools/versionchooser.py +1 -1
  230. psychopy/visual/backends/pygletbackend.py +26 -8
  231. psychopy/visual/basevisual.py.orig +1723 -0
  232. psychopy/visual/form.py.orig +1181 -0
  233. psychopy/visual/text.py.orig +752 -0
  234. psychopy/visual/textbox2/textbox2.py.orig +1315 -0
  235. psychopy/visual/window.py +13 -5
  236. psychopy/visual/windowwarp.py.orig +463 -0
  237. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/METADATA +9 -9
  238. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/RECORD +244 -78
  239. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/WHEEL +1 -1
  240. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/entry_points.txt +2 -0
  241. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  242. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  243. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  244. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  245. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  246. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  247. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  248. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  249. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  250. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  251. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  252. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  253. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  254. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  255. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  256. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  257. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  258. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  259. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  260. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  261. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  262. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  263. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  264. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  265. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  266. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  267. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  268. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  269. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  270. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  271. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  272. psychopy-2024.2.1.dist-info/licenses/AUTHORS.md +0 -138
  273. /psychopy/{app/locale/ar_001/LC_MESSAGE → demos/builder}/.DS_Store +0 -0
  274. /psychopy/{app/locale/es_ES/LC_MESSAGE → demos/builder/Experiments}/.DS_Store +0 -0
  275. /psychopy/{visual → demos/builder/Tools/gammaCalibration/data}/.DS_Store +0 -0
  276. {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,168 @@
1
+ 33.3484 DATA Keypress: lcommand
2
+ 33.8965 EXP Created window1 = Window(allowGUI=True, allowStencil=False, autoLog=True, backendConf=UNKNOWN, bitsMode=UNKNOWN, blendMode='avg', bpc=(8, 8, 8), color=array([0, 0, 0]), colorSpace='rgb', depthBits=8, fullscr=<method-wrapper '__getattribute__' of attributeSetter object at 0x7f833a66c828>, gamma=None, gammaErrorPolicy='raise', lms=UNKNOWN, monitor=<psychopy.monitors.calibTools.Monitor object at 0x7f833b62bba8>, multiSample=False, name='window1', numSamples=2, pos=[696.0, 410.0], screen=0, size=array([1600, 1200]), stencilBits=0, stereo=False, units='height', useFBO=True, useRetina=True, viewOri=0.0, viewPos=None, viewScale=None, waitBlanking=True, winType='pyglet')
3
+ 33.8967 EXP window1: mouseVisible = True
4
+ 33.8967 EXP window1: recordFrameIntervals = False
5
+ 34.0620 EXP window1: recordFrameIntervals = True
6
+ 34.2144 WARNING t of last frame was 22.15ms (=1/45)
7
+ 34.7249 WARNING t of last frame was 32.26ms (=1/31)
8
+ 34.7468 WARNING t of last frame was 21.95ms (=1/45)
9
+ 34.9128 EXP window1: recordFrameIntervals = False
10
+ 35.6135 EXP Created blockIntroText = TextStim(__class__=<class 'psychopy.visual.text.TextStim'>, alignHoriz=method-wrapper(...), alignText='center', alignVert=method-wrapper(...), anchorHoriz='center', anchorVert='center', antialias=True, autoLog=True, bold=False, color=array([1, 1, 1]), colorSpace='rgb', contrast=1.0, depth=0.0, flipHoriz=False, flipVert=False, font='Arial', fontFiles=[], height=0.1, italic=False, languageStyle='LTR', name='blockIntroText', opacity=1, ori=0, pos=array([0., 0.]), rgb=UNKNOWN, text="You're about to start a new block", units='height', win=Window(...), wrapWidth=1)
11
+ 35.6143 EXP Created stimInfo = TextStim(__class__=<class 'psychopy.visual.text.TextStim'>, alignHoriz=method-wrapper(...), alignText='center', alignVert=method-wrapper(...), anchorHoriz='center', anchorVert='center', antialias=True, autoLog=True, bold=False, color=array([1, 1, 1]), colorSpace='rgb', contrast=1.0, depth=0.0, flipHoriz=False, flipVert=False, font='Arial', fontFiles=[], height=0.1, italic=False, languageStyle='LTR', name='stimInfo', opacity=1, ori=0, pos=array([0., 0.]), rgb=UNKNOWN, text='', units='height', win=Window(...), wrapWidth=1)
12
+ 35.6147 EXP Created sequence: random, trialTypes=1, nReps=4, seed=None
13
+ 35.6149 EXP New trial (rep=0, index=0): None
14
+ 35.6409 EXP blockIntroText: autoDraw = True
15
+ 36.1161 EXP Created sequence: random, trialTypes=1, nReps=2, seed=None
16
+ 36.1163 EXP New trial (rep=0, index=0): None
17
+ 36.1166 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
18
+ 36.1167 EXP New trial (rep=0, index=0): None
19
+ 36.1268 EXP blockIntroText: autoDraw = False
20
+ 36.1268 EXP stimInfo: text = 'stim 0'
21
+ 36.2098 EXP stimInfo: autoDraw = True
22
+ 36.2938 EXP New trial (rep=1, index=0): None
23
+ 36.2972 EXP stimInfo: autoDraw = False
24
+ 36.2972 EXP stimInfo: autoDraw = False
25
+ 36.2972 EXP stimInfo: text = 'stim 1'
26
+ 36.3680 EXP stimInfo: autoDraw = True
27
+ 36.4529 EXP New trial (rep=2, index=0): None
28
+ 36.4602 EXP stimInfo: autoDraw = False
29
+ 36.4602 EXP stimInfo: autoDraw = False
30
+ 36.4602 EXP stimInfo: text = 'stim 2'
31
+ 36.5320 EXP stimInfo: autoDraw = True
32
+ 36.6197 EXP New trial (rep=1, index=0): None
33
+ 36.6200 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
34
+ 36.6202 EXP New trial (rep=0, index=0): None
35
+ 36.6233 EXP stimInfo: autoDraw = False
36
+ 36.6233 EXP stimInfo: autoDraw = False
37
+ 36.6233 EXP stimInfo: text = 'stim 0'
38
+ 36.7158 EXP stimInfo: autoDraw = True
39
+ 36.7994 EXP New trial (rep=1, index=0): None
40
+ 36.8023 EXP stimInfo: autoDraw = False
41
+ 36.8023 EXP stimInfo: autoDraw = False
42
+ 36.8023 EXP stimInfo: text = 'stim 1'
43
+ 36.8714 EXP stimInfo: autoDraw = True
44
+ 36.9553 EXP New trial (rep=2, index=0): None
45
+ 36.9581 EXP stimInfo: autoDraw = False
46
+ 36.9581 EXP stimInfo: autoDraw = False
47
+ 36.9581 EXP stimInfo: text = 'stim 2'
48
+ 37.0264 EXP stimInfo: autoDraw = True
49
+ 37.1406 EXP New trial (rep=1, index=0): None
50
+ 37.1446 EXP stimInfo: autoDraw = False
51
+ 37.1446 EXP stimInfo: autoDraw = False
52
+ 37.1446 EXP blockIntroText: autoDraw = True
53
+ 37.6302 EXP Created sequence: random, trialTypes=1, nReps=2, seed=None
54
+ 37.6304 EXP New trial (rep=0, index=0): None
55
+ 37.6306 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
56
+ 37.6308 EXP New trial (rep=0, index=0): None
57
+ 37.6339 EXP blockIntroText: autoDraw = False
58
+ 37.6339 EXP blockIntroText: autoDraw = False
59
+ 37.6339 EXP stimInfo: text = 'stim 0'
60
+ 37.7138 EXP stimInfo: autoDraw = True
61
+ 37.7979 EXP New trial (rep=1, index=0): None
62
+ 37.8006 EXP stimInfo: autoDraw = False
63
+ 37.8006 EXP stimInfo: autoDraw = False
64
+ 37.8006 EXP stimInfo: text = 'stim 1'
65
+ 37.8698 EXP stimInfo: autoDraw = True
66
+ 37.9535 EXP New trial (rep=2, index=0): None
67
+ 37.9561 EXP stimInfo: autoDraw = False
68
+ 37.9561 EXP stimInfo: autoDraw = False
69
+ 37.9561 EXP stimInfo: text = 'stim 2'
70
+ 38.0249 EXP stimInfo: autoDraw = True
71
+ 38.1085 EXP New trial (rep=1, index=0): None
72
+ 38.1087 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
73
+ 38.1089 EXP New trial (rep=0, index=0): None
74
+ 38.1116 EXP stimInfo: autoDraw = False
75
+ 38.1116 EXP stimInfo: autoDraw = False
76
+ 38.1116 EXP stimInfo: text = 'stim 0'
77
+ 38.1800 EXP stimInfo: autoDraw = True
78
+ 38.2633 EXP New trial (rep=1, index=0): None
79
+ 38.2660 EXP stimInfo: autoDraw = False
80
+ 38.2660 EXP stimInfo: autoDraw = False
81
+ 38.2660 EXP stimInfo: text = 'stim 1'
82
+ 38.3351 EXP stimInfo: autoDraw = True
83
+ 38.4183 EXP New trial (rep=2, index=0): None
84
+ 38.4214 EXP stimInfo: autoDraw = False
85
+ 38.4214 EXP stimInfo: autoDraw = False
86
+ 38.4214 EXP stimInfo: text = 'stim 2'
87
+ 38.4896 EXP stimInfo: autoDraw = True
88
+ 38.6173 EXP New trial (rep=2, index=0): None
89
+ 38.6215 EXP stimInfo: autoDraw = False
90
+ 38.6215 EXP stimInfo: autoDraw = False
91
+ 38.6215 EXP blockIntroText: autoDraw = True
92
+ 39.1054 EXP Created sequence: random, trialTypes=1, nReps=2, seed=None
93
+ 39.1055 EXP New trial (rep=0, index=0): None
94
+ 39.1057 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
95
+ 39.1058 EXP New trial (rep=0, index=0): None
96
+ 39.1088 EXP blockIntroText: autoDraw = False
97
+ 39.1088 EXP blockIntroText: autoDraw = False
98
+ 39.1088 EXP stimInfo: text = 'stim 0'
99
+ 39.1780 EXP stimInfo: autoDraw = True
100
+ 39.2619 EXP New trial (rep=1, index=0): None
101
+ 39.2650 EXP stimInfo: autoDraw = False
102
+ 39.2650 EXP stimInfo: autoDraw = False
103
+ 39.2650 EXP stimInfo: text = 'stim 1'
104
+ 39.3345 EXP stimInfo: autoDraw = True
105
+ 39.4183 EXP New trial (rep=2, index=0): None
106
+ 39.4211 EXP stimInfo: autoDraw = False
107
+ 39.4211 EXP stimInfo: autoDraw = False
108
+ 39.4211 EXP stimInfo: text = 'stim 2'
109
+ 39.4902 EXP stimInfo: autoDraw = True
110
+ 39.5743 EXP New trial (rep=1, index=0): None
111
+ 39.5745 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
112
+ 39.5746 EXP New trial (rep=0, index=0): None
113
+ 39.5774 EXP stimInfo: autoDraw = False
114
+ 39.5774 EXP stimInfo: autoDraw = False
115
+ 39.5774 EXP stimInfo: text = 'stim 0'
116
+ 39.6459 EXP stimInfo: autoDraw = True
117
+ 39.7294 EXP New trial (rep=1, index=0): None
118
+ 39.7326 EXP stimInfo: autoDraw = False
119
+ 39.7326 EXP stimInfo: autoDraw = False
120
+ 39.7326 EXP stimInfo: text = 'stim 1'
121
+ 39.8018 EXP stimInfo: autoDraw = True
122
+ 39.8853 EXP New trial (rep=2, index=0): None
123
+ 39.8880 EXP stimInfo: autoDraw = False
124
+ 39.8880 EXP stimInfo: autoDraw = False
125
+ 39.8880 EXP stimInfo: text = 'stim 2'
126
+ 39.9563 EXP stimInfo: autoDraw = True
127
+ 40.0685 EXP New trial (rep=3, index=0): None
128
+ 40.0724 EXP stimInfo: autoDraw = False
129
+ 40.0724 EXP stimInfo: autoDraw = False
130
+ 40.0724 EXP blockIntroText: autoDraw = True
131
+ 40.5561 EXP Created sequence: random, trialTypes=1, nReps=2, seed=None
132
+ 40.5562 EXP New trial (rep=0, index=0): None
133
+ 40.5564 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
134
+ 40.5565 EXP New trial (rep=0, index=0): None
135
+ 40.5595 EXP blockIntroText: autoDraw = False
136
+ 40.5595 EXP blockIntroText: autoDraw = False
137
+ 40.5595 EXP stimInfo: text = 'stim 0'
138
+ 40.6282 EXP stimInfo: autoDraw = True
139
+ 40.7120 EXP New trial (rep=1, index=0): None
140
+ 40.7156 EXP stimInfo: autoDraw = False
141
+ 40.7156 EXP stimInfo: autoDraw = False
142
+ 40.7156 EXP stimInfo: text = 'stim 1'
143
+ 40.7845 EXP stimInfo: autoDraw = True
144
+ 40.8684 EXP New trial (rep=2, index=0): None
145
+ 40.8712 EXP stimInfo: autoDraw = False
146
+ 40.8712 EXP stimInfo: autoDraw = False
147
+ 40.8712 EXP stimInfo: text = 'stim 2'
148
+ 40.9400 EXP stimInfo: autoDraw = True
149
+ 41.0239 EXP New trial (rep=1, index=0): None
150
+ 41.0241 EXP Created sequence: random, trialTypes=1, nReps=3, seed=None
151
+ 41.0243 EXP New trial (rep=0, index=0): None
152
+ 41.0270 EXP stimInfo: autoDraw = False
153
+ 41.0270 EXP stimInfo: autoDraw = False
154
+ 41.0270 EXP stimInfo: text = 'stim 0'
155
+ 41.0959 EXP stimInfo: autoDraw = True
156
+ 41.1788 EXP New trial (rep=1, index=0): None
157
+ 41.1816 EXP stimInfo: autoDraw = False
158
+ 41.1816 EXP stimInfo: autoDraw = False
159
+ 41.1816 EXP stimInfo: text = 'stim 1'
160
+ 41.2501 EXP stimInfo: autoDraw = True
161
+ 41.3342 EXP New trial (rep=2, index=0): None
162
+ 41.3371 EXP stimInfo: autoDraw = False
163
+ 41.3371 EXP stimInfo: autoDraw = False
164
+ 41.3371 EXP stimInfo: text = 'stim 2'
165
+ 41.4059 EXP stimInfo: autoDraw = True
166
+ 41.5522 EXP stimInfo: autoDraw = False
167
+ 41.5522 EXP stimInfo: autoDraw = False
168
+ 41.5612 EXP window1: mouseVisible = True
Binary file
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Thu May 8 10:46:41 2014
4
+
5
+ @author: jon.peirce
6
+ """
7
+ import pytest
8
+ from psychopy import visual, core
9
+ from psychopy.hardware import crs
10
+
11
+
12
+ def test_bitsSharp():
13
+ win = visual.Window(screen=1, fullscr=True, useFBO=True, autoLog=True)
14
+ win.setGamma(1.0) #make sure gfx card LUT is identity
15
+ #initialise BitsSharp
16
+ try:
17
+ bits = crs.BitsSharp(win=win, mode='color++')
18
+ except ImportError:
19
+ pytest.skip("crs.BitsSharp: could not initialize. possible:\nfrom serial.tools import list_ports\n"
20
+ "ImportError: No module named tools")
21
+
22
+ if not bits.OK:
23
+ win.close()
24
+ pytest.skip("No BitsSharp connected")
25
+
26
+ print(bits.info)
27
+
28
+ #switch to status screen (while keeping in mono 'mode')
29
+ bits.getVideoLine(lineN=1, nPixels=1)
30
+ core.wait(5) #wait for status mode to take effect
31
+
32
+ <<<<<<< HEAD
33
+ #createa stimulus to check luminance values
34
+ screenSqr = visual.GratingStim(win, tex=None, mask=None, size=2)
35
+ =======
36
+ #create a stimulus to check luminance values
37
+ screenSqr = visual.GratingStim(win,tex=None, mask=None,
38
+ size=2)
39
+ >>>>>>> release
40
+
41
+ print('\n up from zero:')
42
+ bit16 = (2.0 ** 16) - 1
43
+ for frameN in range(5):
44
+ intensity = frameN / bit16
45
+ screenSqr.color = intensity * 2 - 1 # psychopy is -1:1
46
+ screenSqr.draw()
47
+ win.flip()
48
+ pixels = bits.getVideoLine(lineN=1, nPixels=2)
49
+ print(pixels[0], pixels[1], intensity)
50
+
51
+ print('\n down from 1:')
52
+ for frameN in range(5):
53
+ intensity = 1 - (frameN / bit16)
54
+ screenSqr.color = intensity * 2 - 1 # psychopy is -1:1
55
+ screenSqr.draw()
56
+ win.flip()
57
+ pixels = bits.getVideoLine(lineN=1, nPixels=2)
58
+ print(pixels[0], pixels[1], intensity)
59
+
60
+ print('\n check the middle::')
61
+ for intensity in [0.5, 0.5 + (1 / bit16)]:
62
+ screenSqr.color = intensity * 2 - 1 # psychopy is -1:1
63
+ screenSqr.draw()
64
+ win.flip()
65
+ pixels = bits.getVideoLine(lineN=1, nPixels=2)
66
+ print(pixels[0], pixels[1], intensity)
67
+
68
+ bits.mode = "color++" #get out of status screen
@@ -128,3 +128,115 @@ def test_AliasDict():
128
128
  params2.alias("1", alias="one")
129
129
  assert "one" not in params.aliases
130
130
  assert "1" not in params.aliases
131
+
132
+
133
+ class TestIndexDict:
134
+ def setup_method(self):
135
+ self.recreateData()
136
+
137
+ def recreateData(self):
138
+ """
139
+ Recreate the test index dict from scratch, in case it changed over the course of a test.
140
+ """
141
+ self.data = at.IndexDict({
142
+ 'someKey': "abc",
143
+ 'someOtherKey': "def",
144
+ 'anotherOne': "ghi",
145
+ 1: "jkl",
146
+ })
147
+
148
+ def test_isinstance(self):
149
+ """
150
+ Check that an IndexDict is an instance of dict
151
+ """
152
+ assert isinstance(self.data, dict)
153
+
154
+ def test_length(self):
155
+ """
156
+ Check that an IndexDict reports its length as the number of explicit keys, ignoring
157
+ positional indices.
158
+ """
159
+ assert len(self.data) == 4
160
+
161
+ def test_get_item(self):
162
+ """
163
+ Check that items in an IndexDict can be got as expected, explicit keys should always take
164
+ precedence over positional indices.
165
+ """
166
+ cases = [
167
+ # positional indices
168
+ (0, "abc"),
169
+ (2, "ghi"),
170
+ (3, "jkl"),
171
+ # explicit indices
172
+ ('someKey', "abc"),
173
+ ('someOtherKey', "def"),
174
+ ('anotherOne', "ghi"),
175
+ # conflicting indices (should favour explicit)
176
+ (1, "jkl"),
177
+ ]
178
+ # iterate through cases
179
+ for key, value in cases:
180
+ # check that each key returns the correct value
181
+ assert self.data[key] == value
182
+
183
+ def test_set_item(self):
184
+ """
185
+ Check that items in an IndexDict can be set as expected, should set by position only if the
186
+ positional index is not already defined as an explicit key.
187
+ """
188
+ cases = [
189
+ # set by positional index (no conflict)
190
+ {'set': (0, "mno"), 'get': (0, "mno")},
191
+ {'set': (0, "mno"), 'get': ('someKey', "mno")},
192
+ # set by explicit key (no conflict)
193
+ {'set': ('someKey', "mno"), 'get': (0, "mno")},
194
+ {'set': ('someKey', "mno"), 'get': ('someKey', "mno")},
195
+ # set by explicit string (when its positional index is also a key)
196
+ {'set': ('someOtherKey', "pqr"), 'get': ('someOtherKey', "pqr")},
197
+ {'set': ('someOtherKey', "mno"), 'get': (1, "jkl")},
198
+ # set by positional index (when it's also a key)
199
+ {'set': (1, "pqr"), 'get': ('someOtherKey', "def")},
200
+ {'set': (1, "pqr"), 'get': (1, "pqr")},
201
+ # set by explicit key not yet in array
202
+ {'set': ('newKey', "stu"), 'get': ('newKey', "stu")},
203
+ {'set': ('newKey', "stu"), 'get': (4, "stu")},
204
+ # set by positional index not yet in array (should treat as explicit key)
205
+ {'set': (6, "stu"), 'get': (6, "stu")},
206
+ ]
207
+ # iterate through cases
208
+ for case in cases:
209
+ # recreate data to clear last changes
210
+ self.recreateData()
211
+ # get values to set and expected values to return
212
+ seti, setval = case['set']
213
+ geti, getval = case['get']
214
+ # set value
215
+ self.data[seti] = setval
216
+ # check value
217
+ assert self.data[geti] == getval, (
218
+ f"After setting data[{repr(seti)}] = {repr(setval)} expected to get data["
219
+ f"{repr(geti)}] == {repr(getval)}, but instead got data[{repr(geti)}] == "
220
+ f"{repr(self.data[geti])}"
221
+ )
222
+
223
+ def test_key_error(self):
224
+ """
225
+ Check that supplying an invalid key/index to an IndexDict still errors like a normal
226
+ dict/list
227
+ """
228
+ cases = [
229
+ # index bigger than array
230
+ (4, KeyError, "4 should be out of bounds, but got {}"),
231
+ # key not in array
232
+ ('lalala', KeyError, "There shouldn't be a value for 'lalala', but got {}"),
233
+ ]
234
+ for i, errType, msg in cases:
235
+ try:
236
+ val = self.data[i]
237
+ except errType as err:
238
+ # if it errors as expected, good!
239
+ pass
240
+ else:
241
+ # if no error, raise an assertion error with message
242
+ raise AssertionError(msg.format(val))
@@ -0,0 +1,219 @@
1
+ from pathlib import Path
2
+
3
+ from psychopy import visual, colors, core
4
+ from .test_basevisual import _TestUnitsMixin
5
+ from psychopy.tests.test_experiment.test_component_compile_python import _TestBoilerplateMixin
6
+ from .. import utils
7
+
8
+ from ..utils import TESTS_DATA_PATH
9
+
10
+
11
+ class TestImage(_TestUnitsMixin, _TestBoilerplateMixin):
12
+ """
13
+ Test that images render as expected. Note: In BaseVisual tests, image colors will look different than
14
+ seems intuitive as foreColor will be set to `"blue"`.
15
+ """
16
+ def setup(self):
17
+ self.win = visual.Window()
18
+ self.obj = visual.ImageStim(
19
+ self.win,
20
+ str(Path(TESTS_DATA_PATH) / 'testimage.jpg'),
21
+ colorSpace='rgb1',
22
+ )
23
+
24
+ def test_anchor_flip(self):
25
+ """
26
+ Check that flipping the image doesn't flip the direction of the anchor
27
+ """
28
+ # Setup obj
29
+ self.obj.units = "height"
30
+ self.obj.pos = (0, 0)
31
+ self.obj.size = (0.5, 0.5)
32
+ self.obj.anchor = "bottom left"
33
+ # Flip vertically
34
+ self.obj.flipVert = True
35
+ self.obj.flipHoriz = False
36
+ # Check
37
+ self.win.flip()
38
+ self.obj.draw()
39
+ # self.win.getMovieFrame(buffer='back').save(Path(utils.TESTS_DATA_PATH) / "test_image_flip_anchor_vert.png")
40
+ utils.compareScreenshot("test_image_flip_anchor_vert.png", self.win, crit=7)
41
+ # Flip horizontally
42
+ self.obj.flipVert = False
43
+ self.obj.flipHoriz = True
44
+ # Check
45
+ self.win.flip()
46
+ self.obj.draw()
47
+ # self.win.getMovieFrame(buffer='back').save(Path(utils.TESTS_DATA_PATH) / "test_image_flip_anchor_horiz.png")
48
+ utils.compareScreenshot("test_image_flip_anchor_horiz.png", self.win, crit=7)
49
+
50
+ <<<<<<< HEAD
51
+ def test_aspect_ratio(self):
52
+ """
53
+ Test that images set with one or both dimensions as None maintain their aspect ratio
54
+ """
55
+ cases = [
56
+ # norm 1:1
57
+ {"img": "default.png", "aspect": (1, 1),
58
+ "size": (None, 2), "units": "norm",
59
+ "tag": "default_xNone_yFull"},
60
+ {"img": "default.png", "aspect": (1, 1),
61
+ "size": (2, None), "units": "norm",
62
+ "tag": "default_xFull_yNone"},
63
+ {"img": "default.png", "aspect": (1, 1),
64
+ "size": (None, None), "units": "norm",
65
+ "tag": "default_xNone_yNone"},
66
+ {"img": "default.png", "aspect": (1, 1),
67
+ "size": None, "units": "norm",
68
+ "tag": "default_None"},
69
+ # height 1:1
70
+ {"img": "default.png", "aspect": (1, 1),
71
+ "size": (None, 1), "units": "height",
72
+ "tag": "default_xNone_yFull"},
73
+ {"img": "default.png", "aspect": (1, 1),
74
+ "size": (1 / self.win.size[1] * self.win.size[0], None), "units": "height",
75
+ "tag": "default_xFull_yNone"},
76
+ {"img": "default.png", "aspect": (1, 1),
77
+ "size": (None, None), "units": "height",
78
+ "tag": "default_xNone_yNone"},
79
+ {"img": "default.png", "aspect": (1, 1),
80
+ "size": None, "units": "height",
81
+ "tag": "default_None"},
82
+ # pix 1:1
83
+ {"img": "default.png", "aspect": (1, 1),
84
+ "size": (None, self.win.size[1]), "units": "pix",
85
+ "tag": "default_xNone_yFull"},
86
+ {"img": "default.png", "aspect": (1, 1),
87
+ "size": (self.win.size[0], None), "units": "pix",
88
+ "tag": "default_xFull_yNone"},
89
+ {"img": "default.png", "aspect": (1, 1),
90
+ "size": (None, None), "units": "pix",
91
+ "tag": "default_xNone_yNone"},
92
+ {"img": "default.png", "aspect": (1, 1),
93
+ "size": None, "units": "pix",
94
+ "tag": "default_None"},
95
+ ]
96
+ for case in cases:
97
+ # Set image
98
+ self.obj.image = case['img']
99
+ # Set size
100
+ self.obj.units = case['units']
101
+ self.obj.size = case['size']
102
+ # Check that aspect ratio is still correct
103
+ assert self.obj.aspectRatio == case['aspect']
104
+ # Check that image looks as expected
105
+ self.obj.draw()
106
+ filename = f"test_image_aspect_{case['tag']}.png"
107
+ # self.win.getMovieFrame(buffer='back').save(Path(utils.TESTS_DATA_PATH) / filename)
108
+ utils.compareScreenshot(Path(utils.TESTS_DATA_PATH) / filename, self.win, crit=7)
109
+ self.win.flip()
110
+ =======
111
+
112
+ class TestImageAnimation:
113
+ """
114
+ Tests for using ImageStim to create frame animations
115
+ """
116
+ @classmethod
117
+ def setup_class(cls):
118
+ nFrames = 16
119
+ # Define array of sizes/desired frame rates
120
+ cls.cases = [
121
+ {'size': 6 ** 2, 'fps': 16},
122
+ {'size': 8 ** 2, 'fps': 16},
123
+ {'size': 10 ** 2, 'fps': 8},
124
+ {'size': 12 ** 2, 'fps': 2},
125
+ ]
126
+ # Create frames
127
+ for i, case in enumerate(cls.cases):
128
+ size = case['size']
129
+ # Create window and shapes
130
+ win = visual.Window(size=(size, size), color='purple')
131
+ shape1 = visual.ShapeStim(win,
132
+ pos=(0.2, 0.2), size=(0.5, 0.5),
133
+ lineWidth=size * 0.1,
134
+ fillColor='red', lineColor='green',
135
+ )
136
+ shape2 = visual.ShapeStim(win,
137
+ pos=(-0.2, -0.2), size=(0.5, 0.5),
138
+ lineWidth=size * 0.1,
139
+ fillColor='blue', lineColor='yellow'
140
+ )
141
+
142
+ frames = []
143
+
144
+ for thisFrame in range(nFrames):
145
+ # Cycle window hue
146
+ win.color = colors.Color(
147
+ (win._color.hsv[0] + 360 * thisFrame / nFrames, win._color.hsv[1], win._color.hsv[2]),
148
+ 'hsv'
149
+ )
150
+ # Cycle shape hues
151
+ shape1._fillColor.hsv = (
152
+ shape1._fillColor.hsv[0] + 360 * thisFrame / nFrames, shape1._fillColor.hsv[1],
153
+ shape1._fillColor.hsv[2]
154
+ )
155
+ shape1._borderColor.hsv = (
156
+ shape1._borderColor.hsv[0] - 360 * thisFrame / nFrames, shape1._borderColor.hsv[1],
157
+ shape1._borderColor.hsv[2]
158
+ )
159
+ shape2._fillColor.hsv = (
160
+ shape2._fillColor.hsv[0] + 360 * thisFrame / nFrames, shape2._fillColor.hsv[1],
161
+ shape2._fillColor.hsv[2]
162
+ )
163
+ shape2._borderColor.hsv = (
164
+ shape2._borderColor.hsv[0] - 360 * thisFrame / nFrames, shape2._borderColor.hsv[1],
165
+ shape2._borderColor.hsv[2]
166
+ )
167
+ # Rotate shapes
168
+ shape1.ori = shape1.ori + 360 * thisFrame / nFrames
169
+ shape2.ori = shape2.ori - 360 * thisFrame / nFrames
170
+ # Render
171
+ win.flip()
172
+ shape1.draw()
173
+ shape2.draw()
174
+ # Get frame
175
+ frame = win.getMovieFrame(buffer='back')
176
+ frames.append(
177
+ frame
178
+ )
179
+
180
+ # Cleanup
181
+ win.close()
182
+ del shape1
183
+ del shape2
184
+ # Update case
185
+ cls.cases[i]['frames'] = frames
186
+
187
+ def test_fps(self):
188
+ """
189
+ Check that images can be updated sufficiently fast to create frame animations
190
+ """
191
+ # Create clock
192
+ clock = core.Clock()
193
+ # Try at each size
194
+ for case in self.cases:
195
+ size = case['size']
196
+ # Make window and image
197
+ win = visual.Window(size=(size, size))
198
+ img = visual.ImageStim(win, units='pix', size=(size, size))
199
+ # Iterate through frames
200
+ refr = []
201
+ for frame in case['frames']:
202
+ # Reset clock
203
+ clock.reset()
204
+ # Set image contents
205
+ img.image = frame
206
+ # Update
207
+ img.draw()
208
+ win.flip()
209
+ # Store time taken
210
+ refr.append(clock.getTime())
211
+ # Print frame rate for this size
212
+ fps = round(1 / max(refr))
213
+ assert fps > case['fps'], (
214
+ f"Max frame rate for {size}x{size} animations should be at least {case['fps']}, but was {fps}"
215
+ )
216
+ # Cleanup
217
+ win.close()
218
+ del img
219
+ >>>>>>> 14bdb82f9dac0abd734f48d14e74d67e0eb3cc50
@@ -21,6 +21,53 @@ import numpy
21
21
  import ctypes
22
22
 
23
23
 
24
+ class IndexDict(dict):
25
+ """
26
+ A dict which allows for keys to be accessed by index as well as by key. Can be initialised
27
+ from a dict, or from a set of keyword arguments.
28
+
29
+ Example
30
+ -------
31
+ ```
32
+ data = IndexDict({
33
+ 'someKey': "abc",
34
+ 'someOtherKey': "def",
35
+ 'anotherOne': "ghi",
36
+ 1: "jkl",
37
+ })
38
+ # using a numeric index will return the value for the key at that position
39
+ print(data[0]) # prints: abc
40
+ # ...unless that number is already a key
41
+ print(data[1]) # prints: jkl
42
+ ```
43
+ """
44
+ def __init__(self, arr=None, **kwargs):
45
+ # initialise dict
46
+ dict.__init__(self)
47
+ # if given no dict, use a blank one
48
+ if arr is None:
49
+ arr = {}
50
+ # if given a dict, update kwargs with it
51
+ kwargs.update(arr)
52
+ # set every key
53
+ for key, value in kwargs.items():
54
+ dict.__setitem__(self, key, value)
55
+
56
+ def __getitem__(self, key):
57
+ # if key is a valid numeric index not present as a normal key, get matching key
58
+ if isinstance(key, int) and key < len(self) and key not in self:
59
+ return list(self.values())[key]
60
+ # index like normal
61
+ return dict.__getitem__(self, key)
62
+
63
+ def __setitem__(self, key, value):
64
+ # if key is a valid numeric index not present as a normal key, get matching key
65
+ if isinstance(key, int) and key < len(self) and key not in self:
66
+ key = list(self.keys())[key]
67
+ # set like normal
68
+ return dict.__setitem__(self, key, value)
69
+
70
+
24
71
  def createXYs(x, y=None):
25
72
  """Create an Nx2 array of XY values including all combinations of the
26
73
  x and y values provided.
@@ -202,7 +202,7 @@ def getPsychoJSVersionStr(currentVersion, preferredVersion=''):
202
202
  # e.g. 2021.1.0 not 2021.1.0.dev3
203
203
  useVerStr = '.'.join(useVerStr.split('.')[:3])
204
204
  # PsychoJS doesn't have additional rc1 or dev1 releases
205
- for versionSuffix in ["rc", "dev", "a", "b"]:
205
+ for versionSuffix in ["rc", "dev", "post", "a", "b"]:
206
206
  if versionSuffix in useVerStr:
207
207
  useVerStr = useVerStr.split(versionSuffix)[0]
208
208