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,562 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ This experiment was created using PsychoPy3 Experiment Builder (v2022.2.0dev3),
5
+ on Wed May 18 14:18:19 2022
6
+ If you publish work using this script the most relevant publication is:
7
+
8
+ Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019)
9
+ PsychoPy2: Experiments in behavior made easy Behav Res 51: 195.
10
+ https://doi.org/10.3758/s13428-018-01193-y
11
+
12
+ """
13
+
14
+ from psychopy import locale_setup
15
+ from psychopy import prefs
16
+ from psychopy import sound, gui, visual, core, data, event, logging, clock, colors, layout
17
+ from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
18
+ STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
19
+
20
+ import numpy as np # whole numpy lib is available, prepend 'np.'
21
+ from numpy import (sin, cos, tan, log, log10, pi, average,
22
+ sqrt, std, deg2rad, rad2deg, linspace, asarray)
23
+ from numpy.random import random, randint, normal, shuffle, choice as randchoice
24
+ import os # handy system and path functions
25
+ import sys # to get file system encoding
26
+
27
+ import psychopy.iohub as io
28
+ from psychopy.hardware import keyboard
29
+
30
+
31
+
32
+ # Ensure that relative paths start from the same directory as this script
33
+ _thisDir = os.path.dirname(os.path.abspath(__file__))
34
+ os.chdir(_thisDir)
35
+ # Store info about the experiment session
36
+ psychopyVersion = '2022.2.0dev3'
37
+ expName = 'gamma_correction_visual' # from the Builder filename that created this script
38
+ expInfo = {'participant': '', 'session': '001'}
39
+ dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
40
+ if dlg.OK == False:
41
+ core.quit() # user pressed cancel
42
+ expInfo['date'] = data.getDateStr() # add a simple timestamp
43
+ expInfo['expName'] = expName
44
+ expInfo['psychopyVersion'] = psychopyVersion
45
+
46
+ # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
47
+ filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
48
+
49
+ # An ExperimentHandler isn't essential but helps with data saving
50
+ thisExp = data.ExperimentHandler(name=expName, version='',
51
+ extraInfo=expInfo, runtimeInfo=None,
52
+ originPath='/Users/lpzjwp/code/psychopy/git/psychopy/demos/builder/Tools/gammaCorrection/gamma_correction_visual_lastrun.py',
53
+ savePickle=True, saveWideText=True,
54
+ dataFileName=filename)
55
+ # save a log file for detail verbose info
56
+ logFile = logging.LogFile(filename+'.log', level=logging.EXP)
57
+ logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file
58
+
59
+ endExpNow = False # flag for 'escape' or other condition => quit the exp
60
+ frameTolerance = 0.001 # how close to onset before 'same' frame
61
+
62
+ # Start Code - component code to be run after the window creation
63
+
64
+ # Setup the Window
65
+ win = visual.Window(
66
+ size=[1440, 900], fullscr=True, screen=0,
67
+ winType='pyglet', allowGUI=False, allowStencil=False,
68
+ monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
69
+ blendMode='avg', useFBO=True,
70
+ units='height')
71
+ # store frame rate of monitor if we can measure it
72
+ expInfo['frameRate'] = win.getActualFrameRate()
73
+ if expInfo['frameRate'] != None:
74
+ frameDur = 1.0 / round(expInfo['frameRate'])
75
+ else:
76
+ frameDur = 1.0 / 60.0 # could not measure, so guess
77
+ # Setup ioHub
78
+ ioConfig = {}
79
+
80
+ # Setup iohub keyboard
81
+ ioConfig['Keyboard'] = dict(use_keymap='psychopy')
82
+
83
+ ioSession = '1'
84
+ if 'session' in expInfo:
85
+ ioSession = str(expInfo['session'])
86
+ ioServer = io.launchHubServer(window=win, **ioConfig)
87
+ eyetracker = None
88
+
89
+ # create a default keyboard (e.g. to check for escape)
90
+ defaultKeyboard = keyboard.Keyboard(backend='iohub')
91
+
92
+ # Initialize components for Routine "setup_trial"
93
+ setup_trialClock = core.Clock()
94
+ # Run 'Begin Experiment' code from set_gamma
95
+ gamma = 1
96
+
97
+ # Initialize components for Routine "frames"
98
+ framesClock = core.Clock()
99
+ luminance_000 = visual.GratingStim(
100
+ win=win, name='luminance_000',units='height',
101
+ tex='resources/low_contrast.png', mask=None, anchor='center',
102
+ ori=1.0, pos=(0, 0), size=(0.5,0.5), sf=5.0, phase=0.0,
103
+ color=[1,1,1], colorSpace='rgb',
104
+ opacity=1.0, contrast=1.0, blendmode='avg',
105
+ texRes=256.0, interpolate=True, depth=0.0)
106
+ second_ord_025 = visual.GratingStim(
107
+ win=win, name='second_ord_025',units='height',
108
+ tex='resources/second_order_tex.png', mask=None, anchor='center',
109
+ ori=1.0, pos=(0, 0), size=(0.5,0.5), sf=5.0, phase=0.25,
110
+ color=[1,1,1], colorSpace='rgb',
111
+ opacity=1.0, contrast=1.0, blendmode='avg',
112
+ texRes=256.0, interpolate=True, depth=-1.0)
113
+ luminance_050 = visual.GratingStim(
114
+ win=win, name='luminance_050',units='height',
115
+ tex='resources/low_contrast.png', mask=None, anchor='center',
116
+ ori=1.0, pos=(0, 0), size=(0.5,0.5), sf=5.0, phase=0.5,
117
+ color=[1,1,1], colorSpace='rgb',
118
+ opacity=1.0, contrast=1.0, blendmode='avg',
119
+ texRes=256.0, interpolate=True, depth=-2.0)
120
+ second_ord_075 = visual.GratingStim(
121
+ win=win, name='second_ord_075',units='height',
122
+ tex='resources/second_order_tex.png', mask=None, anchor='center',
123
+ ori=1.0, pos=(0, 0), size=(0.5,0.5), sf=5.0, phase=0.75,
124
+ color=[1,1,1], colorSpace='rgb',
125
+ opacity=1.0, contrast=1.0, blendmode='avg',
126
+ texRes=256.0, interpolate=True, depth=-3.0)
127
+
128
+ # Initialize components for Routine "response"
129
+ responseClock = core.Clock()
130
+ resp = keyboard.Keyboard()
131
+
132
+ # Initialize components for Routine "feedback"
133
+ feedbackClock = core.Clock()
134
+ show_feedbk = visual.TextBox2(
135
+ win, text='', font='Open Sans',
136
+ pos=(0, 0), letterHeight=0.05,
137
+ size=(None, None), borderWidth=2.0,
138
+ color='white', colorSpace='rgb',
139
+ opacity=None,
140
+ bold=False, italic=False,
141
+ lineSpacing=1.0,
142
+ padding=0.0, alignment='center',
143
+ anchor='center',
144
+ fillColor=None, borderColor=None,
145
+ flipHoriz=False, flipVert=False, languageStyle='LTR',
146
+ editable=False,
147
+ name='show_feedbk',
148
+ autoLog=True,
149
+ )
150
+
151
+ # Create some handy timers
152
+ globalClock = core.Clock() # to track the time since experiment started
153
+ routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine
154
+
155
+ # set up handler to look after randomisation of trials etc
156
+ conditions = data.importConditions('questStairs.xlsx')
157
+ trials = data.MultiStairHandler(stairType='QUEST', name='trials',
158
+ nTrials=30.0,
159
+ conditions=conditions,
160
+ method='random',
161
+ originPath=-1)
162
+ thisExp.addLoop(trials) # add the loop to the experiment
163
+ # initialise values for first condition
164
+ level = trials._nextIntensity # initialise some vals
165
+ condition = trials.currentStaircase.condition
166
+
167
+ for level, condition in trials:
168
+ currentLoop = trials
169
+ # abbreviate parameter names if possible (e.g. rgb=condition.rgb)
170
+ for paramName in condition:
171
+ exec(paramName + '= condition[paramName]')
172
+
173
+ # ------Prepare to start Routine "setup_trial"-------
174
+ continueRoutine = True
175
+ # update component parameters for each repeat
176
+ # Run 'Begin Routine' code from set_gamma
177
+ gamma = level # from staircase
178
+ trials.addOtherData('gamma', level)
179
+
180
+ win.gamma = level
181
+ # Run 'Begin Routine' code from rand_side
182
+ # randomize whether "high gamma" is right or left
183
+ # "high" is where the grating appears to drift if
184
+ # the gamma is too high. Count as "correct" so
185
+ # that next level will reduce.
186
+ if random() > 0.5:
187
+ ori = 180
188
+ high_ans = 'right'
189
+ else:
190
+ ori = 0
191
+ high_ans = 'left'
192
+ # keep track of which components have finished
193
+ setup_trialComponents = []
194
+ for thisComponent in setup_trialComponents:
195
+ thisComponent.tStart = None
196
+ thisComponent.tStop = None
197
+ thisComponent.tStartRefresh = None
198
+ thisComponent.tStopRefresh = None
199
+ if hasattr(thisComponent, 'status'):
200
+ thisComponent.status = NOT_STARTED
201
+ # reset timers
202
+ t = 0
203
+ _timeToFirstFrame = win.getFutureFlipTime(clock="now")
204
+ setup_trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
205
+ frameN = -1
206
+
207
+ # -------Run Routine "setup_trial"-------
208
+ while continueRoutine:
209
+ # get current time
210
+ t = setup_trialClock.getTime()
211
+ tThisFlip = win.getFutureFlipTime(clock=setup_trialClock)
212
+ tThisFlipGlobal = win.getFutureFlipTime(clock=None)
213
+ frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
214
+ # update/draw components on each frame
215
+
216
+ # check for quit (typically the Esc key)
217
+ if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
218
+ core.quit()
219
+
220
+ # check if all components have finished
221
+ if not continueRoutine: # a component has requested a forced-end of Routine
222
+ break
223
+ continueRoutine = False # will revert to True if at least one component still running
224
+ for thisComponent in setup_trialComponents:
225
+ if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
226
+ continueRoutine = True
227
+ break # at least one component has not yet finished
228
+
229
+ # refresh the screen
230
+ if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
231
+ win.flip()
232
+
233
+ # -------Ending Routine "setup_trial"-------
234
+ for thisComponent in setup_trialComponents:
235
+ if hasattr(thisComponent, "setAutoDraw"):
236
+ thisComponent.setAutoDraw(False)
237
+ # the Routine "setup_trial" was not non-slip safe, so reset the non-slip timer
238
+ routineTimer.reset()
239
+
240
+ # set up handler to look after randomisation of conditions etc
241
+ frame_cycles = data.TrialHandler(nReps=5.0, method='sequential',
242
+ extraInfo=expInfo, originPath=-1,
243
+ trialList=[None],
244
+ seed=None, name='frame_cycles')
245
+ thisExp.addLoop(frame_cycles) # add the loop to the experiment
246
+ thisFrame_cycle = frame_cycles.trialList[0] # so we can initialise stimuli with some values
247
+ # abbreviate parameter names if possible (e.g. rgb = thisFrame_cycle.rgb)
248
+ if thisFrame_cycle != None:
249
+ for paramName in thisFrame_cycle:
250
+ exec('{} = thisFrame_cycle[paramName]'.format(paramName))
251
+
252
+ for thisFrame_cycle in frame_cycles:
253
+ currentLoop = frame_cycles
254
+ # abbreviate parameter names if possible (e.g. rgb = thisFrame_cycle.rgb)
255
+ if thisFrame_cycle != None:
256
+ for paramName in thisFrame_cycle:
257
+ exec('{} = thisFrame_cycle[paramName]'.format(paramName))
258
+
259
+ # ------Prepare to start Routine "frames"-------
260
+ continueRoutine = True
261
+ routineTimer.add(0.200000)
262
+ # update component parameters for each repeat
263
+ luminance_000.setOri(ori)
264
+ second_ord_025.setOri(ori)
265
+ luminance_050.setOri(ori)
266
+ second_ord_075.setOri(ori)
267
+ # keep track of which components have finished
268
+ framesComponents = [luminance_000, second_ord_025, luminance_050, second_ord_075]
269
+ for thisComponent in framesComponents:
270
+ thisComponent.tStart = None
271
+ thisComponent.tStop = None
272
+ thisComponent.tStartRefresh = None
273
+ thisComponent.tStopRefresh = None
274
+ if hasattr(thisComponent, 'status'):
275
+ thisComponent.status = NOT_STARTED
276
+ # reset timers
277
+ t = 0
278
+ _timeToFirstFrame = win.getFutureFlipTime(clock="now")
279
+ framesClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
280
+ frameN = -1
281
+
282
+ # -------Run Routine "frames"-------
283
+ while continueRoutine and routineTimer.getTime() > 0:
284
+ # get current time
285
+ t = framesClock.getTime()
286
+ tThisFlip = win.getFutureFlipTime(clock=framesClock)
287
+ tThisFlipGlobal = win.getFutureFlipTime(clock=None)
288
+ frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
289
+ # update/draw components on each frame
290
+
291
+ # *luminance_000* updates
292
+ if luminance_000.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
293
+ # keep track of start time/frame for later
294
+ luminance_000.frameNStart = frameN # exact frame index
295
+ luminance_000.tStart = t # local t and not account for scr refresh
296
+ luminance_000.tStartRefresh = tThisFlipGlobal # on global time
297
+ win.timeOnFlip(luminance_000, 'tStartRefresh') # time at next scr refresh
298
+ luminance_000.setAutoDraw(True)
299
+ if luminance_000.status == STARTED:
300
+ if frameN >= (luminance_000.frameNStart + 3):
301
+ # keep track of stop time/frame for later
302
+ luminance_000.tStop = t # not accounting for scr refresh
303
+ luminance_000.frameNStop = frameN # exact frame index
304
+ win.timeOnFlip(luminance_000, 'tStopRefresh') # time at next scr refresh
305
+ luminance_000.setAutoDraw(False)
306
+
307
+ # *second_ord_025* updates
308
+ if second_ord_025.status == NOT_STARTED and frameN >= 3:
309
+ # keep track of start time/frame for later
310
+ second_ord_025.frameNStart = frameN # exact frame index
311
+ second_ord_025.tStart = t # local t and not account for scr refresh
312
+ second_ord_025.tStartRefresh = tThisFlipGlobal # on global time
313
+ win.timeOnFlip(second_ord_025, 'tStartRefresh') # time at next scr refresh
314
+ second_ord_025.setAutoDraw(True)
315
+ if second_ord_025.status == STARTED:
316
+ if frameN >= (second_ord_025.frameNStart + 3):
317
+ # keep track of stop time/frame for later
318
+ second_ord_025.tStop = t # not accounting for scr refresh
319
+ second_ord_025.frameNStop = frameN # exact frame index
320
+ win.timeOnFlip(second_ord_025, 'tStopRefresh') # time at next scr refresh
321
+ second_ord_025.setAutoDraw(False)
322
+
323
+ # *luminance_050* updates
324
+ if luminance_050.status == NOT_STARTED and frameN >= 6:
325
+ # keep track of start time/frame for later
326
+ luminance_050.frameNStart = frameN # exact frame index
327
+ luminance_050.tStart = t # local t and not account for scr refresh
328
+ luminance_050.tStartRefresh = tThisFlipGlobal # on global time
329
+ win.timeOnFlip(luminance_050, 'tStartRefresh') # time at next scr refresh
330
+ luminance_050.setAutoDraw(True)
331
+ if luminance_050.status == STARTED:
332
+ if frameN >= (luminance_050.frameNStart + 3):
333
+ # keep track of stop time/frame for later
334
+ luminance_050.tStop = t # not accounting for scr refresh
335
+ luminance_050.frameNStop = frameN # exact frame index
336
+ win.timeOnFlip(luminance_050, 'tStopRefresh') # time at next scr refresh
337
+ luminance_050.setAutoDraw(False)
338
+
339
+ # *second_ord_075* updates
340
+ if second_ord_075.status == NOT_STARTED and frameN >= 9:
341
+ # keep track of start time/frame for later
342
+ second_ord_075.frameNStart = frameN # exact frame index
343
+ second_ord_075.tStart = t # local t and not account for scr refresh
344
+ second_ord_075.tStartRefresh = tThisFlipGlobal # on global time
345
+ win.timeOnFlip(second_ord_075, 'tStartRefresh') # time at next scr refresh
346
+ second_ord_075.setAutoDraw(True)
347
+ if second_ord_075.status == STARTED:
348
+ if frameN >= (second_ord_075.frameNStart + 3):
349
+ # keep track of stop time/frame for later
350
+ second_ord_075.tStop = t # not accounting for scr refresh
351
+ second_ord_075.frameNStop = frameN # exact frame index
352
+ win.timeOnFlip(second_ord_075, 'tStopRefresh') # time at next scr refresh
353
+ second_ord_075.setAutoDraw(False)
354
+
355
+ # check for quit (typically the Esc key)
356
+ if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
357
+ core.quit()
358
+
359
+ # check if all components have finished
360
+ if not continueRoutine: # a component has requested a forced-end of Routine
361
+ break
362
+ continueRoutine = False # will revert to True if at least one component still running
363
+ for thisComponent in framesComponents:
364
+ if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
365
+ continueRoutine = True
366
+ break # at least one component has not yet finished
367
+
368
+ # refresh the screen
369
+ if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
370
+ win.flip()
371
+
372
+ # -------Ending Routine "frames"-------
373
+ for thisComponent in framesComponents:
374
+ if hasattr(thisComponent, "setAutoDraw"):
375
+ thisComponent.setAutoDraw(False)
376
+ # completed 5.0 repeats of 'frame_cycles'
377
+
378
+
379
+ # ------Prepare to start Routine "response"-------
380
+ continueRoutine = True
381
+ # update component parameters for each repeat
382
+ resp.keys = []
383
+ resp.rt = []
384
+ _resp_allKeys = []
385
+ # keep track of which components have finished
386
+ responseComponents = [resp]
387
+ for thisComponent in responseComponents:
388
+ thisComponent.tStart = None
389
+ thisComponent.tStop = None
390
+ thisComponent.tStartRefresh = None
391
+ thisComponent.tStopRefresh = None
392
+ if hasattr(thisComponent, 'status'):
393
+ thisComponent.status = NOT_STARTED
394
+ # reset timers
395
+ t = 0
396
+ _timeToFirstFrame = win.getFutureFlipTime(clock="now")
397
+ responseClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
398
+ frameN = -1
399
+
400
+ # -------Run Routine "response"-------
401
+ while continueRoutine:
402
+ # get current time
403
+ t = responseClock.getTime()
404
+ tThisFlip = win.getFutureFlipTime(clock=responseClock)
405
+ tThisFlipGlobal = win.getFutureFlipTime(clock=None)
406
+ frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
407
+ # update/draw components on each frame
408
+
409
+ # *resp* updates
410
+ waitOnFlip = False
411
+ if resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
412
+ # keep track of start time/frame for later
413
+ resp.frameNStart = frameN # exact frame index
414
+ resp.tStart = t # local t and not account for scr refresh
415
+ resp.tStartRefresh = tThisFlipGlobal # on global time
416
+ win.timeOnFlip(resp, 'tStartRefresh') # time at next scr refresh
417
+ resp.status = STARTED
418
+ # keyboard checking is just starting
419
+ waitOnFlip = True
420
+ win.callOnFlip(resp.clock.reset) # t=0 on next screen flip
421
+ if resp.status == STARTED and not waitOnFlip:
422
+ theseKeys = resp.getKeys(keyList=['left','right'], waitRelease=False)
423
+ _resp_allKeys.extend(theseKeys)
424
+ if len(_resp_allKeys):
425
+ resp.keys = _resp_allKeys[-1].name # just the last key pressed
426
+ resp.rt = _resp_allKeys[-1].rt
427
+ # was this correct?
428
+ if (resp.keys == str('right')) or (resp.keys == 'right'):
429
+ resp.corr = 1
430
+ else:
431
+ resp.corr = 0
432
+ # a response ends the routine
433
+ continueRoutine = False
434
+
435
+ # check for quit (typically the Esc key)
436
+ if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
437
+ core.quit()
438
+
439
+ # check if all components have finished
440
+ if not continueRoutine: # a component has requested a forced-end of Routine
441
+ break
442
+ continueRoutine = False # will revert to True if at least one component still running
443
+ for thisComponent in responseComponents:
444
+ if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
445
+ continueRoutine = True
446
+ break # at least one component has not yet finished
447
+
448
+ # refresh the screen
449
+ if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
450
+ win.flip()
451
+
452
+ # -------Ending Routine "response"-------
453
+ for thisComponent in responseComponents:
454
+ if hasattr(thisComponent, "setAutoDraw"):
455
+ thisComponent.setAutoDraw(False)
456
+ # check responses
457
+ if resp.keys in ['', [], None]: # No response was made
458
+ resp.keys = None
459
+ # was no response the correct answer?!
460
+ if str('right').lower() == 'none':
461
+ resp.corr = 1; # correct non-response
462
+ else:
463
+ resp.corr = 0; # failed to respond (incorrectly)
464
+ # store data for trials (MultiStairHandler)
465
+ trials.addResponse(resp.corr, level)
466
+ trials.addOtherData('resp.rt', resp.rt)
467
+ trials.addOtherData('resp.started', resp.tStartRefresh)
468
+ trials.addOtherData('resp.stopped', resp.tStopRefresh)
469
+ # the Routine "response" was not non-slip safe, so reset the non-slip timer
470
+ routineTimer.reset()
471
+
472
+ # ------Prepare to start Routine "feedback"-------
473
+ continueRoutine = True
474
+ routineTimer.add(0.500000)
475
+ # update component parameters for each repeat
476
+ # Run 'Begin Routine' code from make_feedbk
477
+ msg = f"gamma = {level} \nresp:{resp.keys}"
478
+ show_feedbk.reset()
479
+ show_feedbk.setText(msg)
480
+ # keep track of which components have finished
481
+ feedbackComponents = [show_feedbk]
482
+ for thisComponent in feedbackComponents:
483
+ thisComponent.tStart = None
484
+ thisComponent.tStop = None
485
+ thisComponent.tStartRefresh = None
486
+ thisComponent.tStopRefresh = None
487
+ if hasattr(thisComponent, 'status'):
488
+ thisComponent.status = NOT_STARTED
489
+ # reset timers
490
+ t = 0
491
+ _timeToFirstFrame = win.getFutureFlipTime(clock="now")
492
+ feedbackClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
493
+ frameN = -1
494
+
495
+ # -------Run Routine "feedback"-------
496
+ while continueRoutine and routineTimer.getTime() > 0:
497
+ # get current time
498
+ t = feedbackClock.getTime()
499
+ tThisFlip = win.getFutureFlipTime(clock=feedbackClock)
500
+ tThisFlipGlobal = win.getFutureFlipTime(clock=None)
501
+ frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
502
+ # update/draw components on each frame
503
+
504
+ # *show_feedbk* updates
505
+ if show_feedbk.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
506
+ # keep track of start time/frame for later
507
+ show_feedbk.frameNStart = frameN # exact frame index
508
+ show_feedbk.tStart = t # local t and not account for scr refresh
509
+ show_feedbk.tStartRefresh = tThisFlipGlobal # on global time
510
+ win.timeOnFlip(show_feedbk, 'tStartRefresh') # time at next scr refresh
511
+ show_feedbk.setAutoDraw(True)
512
+ if show_feedbk.status == STARTED:
513
+ # is it time to stop? (based on global clock, using actual start)
514
+ if tThisFlipGlobal > show_feedbk.tStartRefresh + 0.5-frameTolerance:
515
+ # keep track of stop time/frame for later
516
+ show_feedbk.tStop = t # not accounting for scr refresh
517
+ show_feedbk.frameNStop = frameN # exact frame index
518
+ win.timeOnFlip(show_feedbk, 'tStopRefresh') # time at next scr refresh
519
+ show_feedbk.setAutoDraw(False)
520
+
521
+ # check for quit (typically the Esc key)
522
+ if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
523
+ core.quit()
524
+
525
+ # check if all components have finished
526
+ if not continueRoutine: # a component has requested a forced-end of Routine
527
+ break
528
+ continueRoutine = False # will revert to True if at least one component still running
529
+ for thisComponent in feedbackComponents:
530
+ if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
531
+ continueRoutine = True
532
+ break # at least one component has not yet finished
533
+
534
+ # refresh the screen
535
+ if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
536
+ win.flip()
537
+
538
+ # -------Ending Routine "feedback"-------
539
+ for thisComponent in feedbackComponents:
540
+ if hasattr(thisComponent, "setAutoDraw"):
541
+ thisComponent.setAutoDraw(False)
542
+ trials.addOtherData('show_feedbk.started', show_feedbk.tStartRefresh)
543
+ trials.addOtherData('show_feedbk.stopped', show_feedbk.tStopRefresh)
544
+ thisExp.nextEntry()
545
+
546
+ # all staircases completed
547
+
548
+
549
+ # Flip one final time so any remaining win.callOnFlip()
550
+ # and win.timeOnFlip() tasks get executed before quitting
551
+ win.flip()
552
+
553
+ # these shouldn't be strictly necessary (should auto-save)
554
+ thisExp.saveAsWideText(filename+'.csv', delim='auto')
555
+ thisExp.saveAsPickle(filename)
556
+ logging.flush()
557
+ # make sure everything is closed down
558
+ if eyetracker:
559
+ eyetracker.setConnectionState(False)
560
+ thisExp.abort() # or data files will save again on exit
561
+ win.close()
562
+ core.quit()
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Determine screen gamma using motion-nulling method
6
+ of Ledgeway and Smith, 1994, Vision Research, 34, 2727-2740
7
+ A similar system had been used early for chromatic isoluminance:
8
+ Anstis SM, Cavanagh P. A minimum motion technique for judging equiluminance.
9
+ In: Sharpe MJD & LT Colour vision: Psychophysics and physiology. London: Academic Press; 1983. pp. 66-77.
10
+
11
+ Instructions: on each trial press the up/down cursor keys depending on
12
+ the apparent direction of motion of the bars.
13
+ """
14
+
15
+ from psychopy import visual, core, event, gui, data
16
+ from psychopy.tools.filetools import fromFile, toFile
17
+ from psychopy.visual import filters
18
+ import numpy as num
19
+ import time
20
+
21
+ """
22
+ Create a single cycle of noise texture, suitable for checking the
23
+ quality of screen linearisation
24
+ """
25
+
26
+ pixels = 128
27
+ win = visual.Window((pixels, pixels), units='pix', allowGUI=True, bitsMode=None)
28
+ visual.TextStim(win, text='building stimuli').draw()
29
+
30
+ win.flip()
31
+
32
+ globalClock = core.Clock()
33
+
34
+ # for luminance modulated noise
35
+ noiseMatrix = num.random.randint(0, 2, [pixels, pixels]) # * noiseContrast
36
+ noiseMatrix = noiseMatrix * 2.0-1 # into range -1: 1
37
+ lumGrating = filters.makeGrating(pixels, 0, 1, phase=0)
38
+
39
+ second_order = visual.GratingStim(
40
+ win, texRes=pixels, mask=None,
41
+ size=2, units='norm',
42
+ tex= (noiseMatrix * (lumGrating/2+0.5))
43
+ )
44
+ second_order.draw()
45
+ win.flip()
46
+ win.getMovieFrame()
47
+ win.saveMovieFrames('second_order_tex.png')
48
+
49
+ low_contrast = visual.GratingStim(
50
+ win, texRes=pixels, mask=None,
51
+ size=2, units='norm',
52
+ tex= lumGrating, contrast=0.2,
53
+ )
54
+ low_contrast.draw()
55
+ win.flip()
56
+ win.getMovieFrame()
57
+ win.saveMovieFrames('low_contrast.png')
58
+
59
+ # The contents of this file are in the public domain.
Binary file
@@ -0,0 +1 @@
1
+ ioHub PID: 15069
@@ -0,0 +1 @@
1
+ ioHub PID: 15097
Binary file
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Demo: Contracting radial grating
6
+ """
7
+
8
+ from psychopy import visual, event, core
9
+
10
+ win = visual.Window([800, 800])
11
+ globalClock = core.Clock()
12
+
13
+ # Make two wedges (in opposite contrast) and alternate them for flashing
14
+ radialGrating = visual.RadialStim(win, tex='sinXsin', color=1, size=1,
15
+ visibleWedge=[0, 360], radialCycles=4, angularCycles=0,
16
+ autoLog=False) # this stim changes too much for autologging to be useful
17
+
18
+ t = 0
19
+ contractRate = 0.01 # cycles per sec
20
+ while not event.getKeys():
21
+ t = globalClock.getTime()
22
+ radialGrating.radialPhase -= contractRate
23
+ radialGrating.draw()
24
+ win.flip()
25
+
26
+ win.close()
27
+ core.quit()
28
+
29
+ # The contents of this file are in the public domain.