OSCR

OPM-MEG reveals dynamics of beta bursts underlying attentional processes in sensory cortex

Code ↔ Paper

The paper beside its authors' code: matches between them have not been computed for this paper yet.

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 993 lines · 51 KB · no license

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This experiment was created using PsychoPy3 Experiment Builder (v2021.2.3),
  5. on February 17, 2022, at 16:32
  6. If you publish work using this script the most relevant publication is:
  7. Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019)
  8. PsychoPy2: Experiments in behavior made easy Behav Res 51: 195.
  9. https://doi.org/10.3758/s13428-018-01193-y
  10. """
  11. from __future__ import absolute_import, division
  12. from turtle import left
  13. from psychopy import locale_setup
  14. from psychopy import prefs
  15. from psychopy import sound, gui, visual, core, data, event, logging, clock, colors, parallel
  16. from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
  17. STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
  18. import psychopy
  19. import numpy as np # whole numpy lib is available, prepend 'np.'
  20. from numpy import (sin, cos, tan, log, log10, pi, average,
  21. sqrt, std, deg2rad, rad2deg, linspace, asarray)
  22. from numpy.random import random, randint, normal, shuffle, choice as randchoice
  23. import os # handy system and path functions
  24. import sys # to get file system encoding
  25. from psychopy.hardware import keyboard
  26. # Ensure that relative paths start from the same directory as this script
  27. _thisDir = os.path.dirname(os.path.abspath(__file__))
  28. os.chdir(_thisDir)
  29. # Store info about the experiment session
  30. psychopyVersion = '2021.2.3'
  31. expName = 'Braille_Stim_Final' # from the Builder filename that created this script
  32. expInfo = {'participant': '', 'session': '001'}
  33. dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
  34. if dlg.OK == False:
  35. core.quit() # user pressed cancel
  36. expInfo['date'] = data.getDateStr() # add a simple timestamp
  37. expInfo['expName'] = expName
  38. expInfo['psychopyVersion'] = psychopyVersion
  39. # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
  40. filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
  41. # An ExperimentHandler isn't essential but helps with data saving
  42. thisExp = data.ExperimentHandler(name=expName, version='',
  43. extraInfo=expInfo, runtimeInfo=None,
  44. originPath='C:\\Users\\physicsuser\\Documents\\MATLAB\\gonzalo\\Braille_paradigm\\Braille_Stim_Final.py',
  45. savePickle=True, saveWideText=True,
  46. dataFileName=filename)
  47. # save a log file for detail verbose info
  48. logFile = logging.LogFile(filename+'.log', level=logging.EXP)
  49. logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file
  50. endExpNow = False # flag for 'escape' or other condition => quit the exp
  51. frameTolerance = 0.001 # how close to onset before 'same' frame
  52. # Start Code - component code to be run after the window creation
  53. from utils.braille_functions import toBraille, sendStim
  54. # Setup the Window
  55. win = visual.Window(
  56. size=(1024, 768), fullscr=True, screen=0,
  57. winType='pyglet', allowGUI=False, allowStencil=False,
  58. monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
  59. blendMode='avg', useFBO=True,
  60. units='height')
  61. # store frame rate of monitor if we can measure it
  62. expInfo['frameRate'] = win.getActualFrameRate()
  63. if expInfo['frameRate'] != None:
  64. frameDur = 1.0 / round(expInfo['frameRate'])
  65. else:
  66. frameDur = 1.0 / 60.0 # could not measure, so guess
  67. # Setup eyetracking
  68. ioDevice = ioConfig = ioSession = ioServer = eyetracker = None
  69. # create a default keyboard (e.g. to check for escape)
  70. defaultKeyboard = keyboard.Keyboard()
  71. # Initialize components for Routine "trial"
  72. trialClock = core.Clock()
  73. new_trial_text = visual.TextStim(win=win, name='new_trial_text',
  74. text='New trial',
  75. font='Open Sans',
  76. pos=(0, 0), height=0.1, wrapWidth=None, ori=0.0,
  77. color='white', colorSpace='rgb', opacity=None,
  78. languageStyle='LTR',
  79. depth=0.0);
  80. true_pattern = parallel.ParallelPort(address='0xDFF8 ')
  81. cross = visual.ShapeStim(
  82. win=win, name='cross', vertices='cross',
  83. size=(0.1, 0.1),
  84. ori=0.0, pos=(0, 0),
  85. lineWidth=1.0, colorSpace='rgb', lineColor='white', fillColor='white',
  86. opacity=None, depth=-2.0, interpolate=True)
  87. cue_right = visual.ShapeStim(
  88. win=win, name='cue_right', vertices=[(-0.4,0.05),(-0.4,-0.05),(-.2,-0.05),(-.2,-0.1),(0,0),(-.2,0.1),(-.2,0.05)],
  89. size=(0.25, 0.25),
  90. ori=0.0, pos=(0, 0),
  91. lineWidth=1.0, colorSpace='rgb', lineColor='white', fillColor='white',
  92. opacity=None, depth=-3.0, interpolate=True)
  93. cue_left = visual.ShapeStim(
  94. win=win, name='cue_left', vertices=[(0.4,0.05),(0.4,-0.05),(.2,-0.05),(.2,-0.1),(0,0),(.2,0.1),(.2,0.05)],
  95. size=(0.25, 0.25),
  96. ori=0.0, pos=(0, 0),
  97. lineWidth=1.0, colorSpace='rgb', lineColor='white', fillColor='white',
  98. opacity=None, depth=-4.0, interpolate=True)
  99. pattern1 = parallel.ParallelPort(address='0xDFF8 ')
  100. button_resp1 = keyboard.Keyboard()
  101. pattern2 = parallel.ParallelPort(address='0xDFF8 ')
  102. button_resp2 = keyboard.Keyboard()
  103. pattern3 = parallel.ParallelPort(address='0xDFF8 ')
  104. button_resp3 = keyboard.Keyboard()
  105. pattern4 = parallel.ParallelPort(address='0xDFF8 ')
  106. button_resp4 = keyboard.Keyboard()
  107. pattern5 = parallel.ParallelPort(address='0xDFF8 ')
  108. button_resp5 = keyboard.Keyboard()
  109. cross2 = visual.ShapeStim(
  110. win=win, name='cross2', vertices='cross',
  111. size=(0.1, 0.1),
  112. ori=0.0, pos=(0, 0),
  113. lineWidth=1.0, colorSpace='rgb', lineColor='white', fillColor='white',
  114. opacity=None, depth=-15.0, interpolate=True)
  115. # Initialize components for Routine "feedback"
  116. feedbackClock = core.Clock()
  117. feedback_string = visual.TextStim(win=win, name='feedback_string',
  118. text='This is the feedback routine',
  119. font='Open Sans',
  120. pos=(0, 0), height=0.1, wrapWidth=None, ori=0.0,
  121. color='white', colorSpace='rgb', opacity=None,
  122. languageStyle='LTR',
  123. depth=0.0);
  124. # Create some handy timers
  125. globalClock = core.Clock() # to track the time since experiment started
  126. routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine
  127. # set up handler to look after randomisation of conditions etc
  128. Paradigm = data.TrialHandler(nReps=8.0, method='sequential',
  129. extraInfo=expInfo, originPath=-1,
  130. trialList=[None],
  131. seed=None, name='Paradigm')
  132. thisExp.addLoop(Paradigm) # add the loop to the experiment
  133. thisParadigm = Paradigm.trialList[0] # so we can initialise stimuli with some values
  134. # abbreviate parameter names if possible (e.g. rgb = thisParadigm.rgb)
  135. if thisParadigm != None:
  136. for paramName in thisParadigm:
  137. exec('{} = thisParadigm[paramName]'.format(paramName))
  138. # Set up paradigm variables
  139. AttendHand = [] # list of cues
  140. pp = np.array(
  141. [ [1, 1, 0, 0, 1, 1, 0, 0],
  142. [0, 0, 1, 1, 0, 0, 1, 1],
  143. [0, 1, 1, 0, 0, 1, 1, 0],
  144. [1, 1, 1, 1, 0, 0, 0, 0],
  145. [0, 0, 0, 0, 1, 1, 1, 1]
  146. ]
  147. ) # Possible braille patterns
  148. patterns = []
  149. all_down = toBraille(np.zeros([1,8],dtype="int32"),0)
  150. # Define trigger channels
  151. START_trig = 1
  152. SAMPLE_trig = 2
  153. # Pattern triggers
  154. TRUE_trig = 4
  155. FALSEL_trig = 3
  156. FALSER_trig = 5
  157. CUELEFT_trig = 6
  158. CUERIGHT_trig = 7
  159. LEFT_PRESS = 8
  160. RIGHT_PRESS = 16
  161. # Create port object to send the triggers
  162. trigport = parallel.ParallelPort(address='0xDFF8 ')
  163. # Create variables to keep track of presses for the feedback
  164. totalpresses = 0
  165. true_patterns_sent = 0
  166. correctpresses = 0
  167. true_pattern_chosen = []
  168. left_keys = ['b','y']
  169. right_keys = ['r','g']
  170. for thisParadigm in Paradigm:
  171. currentLoop = Paradigm
  172. # abbreviate parameter names if possible (e.g. rgb = thisParadigm.rgb)
  173. if thisParadigm != None:
  174. for paramName in thisParadigm:
  175. exec('{} = thisParadigm[paramName]'.format(paramName))
  176. # set up handler to look after randomisation of conditions etc
  177. first_set = data.TrialHandler(nReps=10.0, method='sequential',
  178. extraInfo=expInfo, originPath=-1,
  179. trialList=[None],
  180. seed=None, name='first_set')
  181. thisExp.addLoop(first_set) # add the loop to the experiment
  182. thisFirst_set = first_set.trialList[0] # so we can initialise stimuli with some values
  183. # Choose random cues for the 10 trials 1 is for left, 2 is for right
  184. Cues = np.append(np.ones([int(first_set.nReps/2),1]), 2*np.ones([int(first_set.nReps/2),1]))
  185. Cues = np.random.permutation(Cues)
  186. AttendHand.append(Cues)
  187. # Choose how many target patterns there will be per trial
  188. g = np.random.gamma(4, 0.3, first_set.nReps)
  189. g = np.round(g)
  190. g[g>5] = 5
  191. # abbreviate parameter names if possible (e.g. rgb = thisFirst_set.rgb)
  192. if thisFirst_set != None:
  193. for paramName in thisFirst_set:
  194. exec('{} = thisFirst_set[paramName]'.format(paramName))
  195. for thisFirst_set in first_set:
  196. # Choose the patterns to send
  197. r = np.random.randint(0,pp.shape[0]) # Choose the true pattern
  198. true_pattern_chosen.append(r)
  199. true_patterns = g[first_set.thisN]
  200. stimuli = np.array([range(0,pp.shape[0])])
  201. np.place(stimuli, stimuli==r, np.random.randint(0,pp.shape[0],pp.shape[0]))
  202. stimuli = np.random.permutation(stimuli)
  203. for i in range(0,int(true_patterns)):
  204. index = np.random.randint(0,pp.shape[0])
  205. stimuli[0,index] = r
  206. patterns.append(stimuli)
  207. currentLoop = first_set
  208. # abbreviate parameter names if possible (e.g. rgb = thisFirst_set.rgb)
  209. if thisFirst_set != None:
  210. for paramName in thisFirst_set:
  211. exec('{} = thisFirst_set[paramName]'.format(paramName))
  212. # ------Prepare to start Routine "trial"-------
  213. continueRoutine = True
  214. routineTimer.add(16.000000)
  215. # update component parameters for each repeat
  216. button_resp1.keys = []
  217. button_resp1.rt = []
  218. _button_resp1_allKeys = []
  219. button_resp2.keys = []
  220. button_resp2.rt = []
  221. _button_resp2_allKeys = []
  222. button_resp3.keys = []
  223. button_resp3.rt = []
  224. _button_resp3_allKeys = []
  225. button_resp4.keys = []
  226. button_resp4.rt = []
  227. _button_resp4_allKeys = []
  228. button_resp5.keys = []
  229. button_resp5.rt = []
  230. _button_resp5_allKeys = []
  231. # keep track of which components have finished
  232. trialComponents = [new_trial_text, true_pattern, cross, cue_right, cue_left, pattern1, button_resp1, pattern2, button_resp2, pattern3, button_resp3, pattern4, button_resp4, pattern5, button_resp5, cross2]
  233. for thisComponent in trialComponents:
  234. thisComponent.tStart = None
  235. thisComponent.tStop = None
  236. thisComponent.tStartRefresh = None
  237. thisComponent.tStopRefresh = None
  238. if hasattr(thisComponent, 'status'):
  239. thisComponent.status = NOT_STARTED
  240. # reset timers
  241. t = 0
  242. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  243. trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
  244. frameN = -1
  245. # Log which hand
  246. if Cues[first_set.thisN] == 2: # Right hand
  247. logging.data("Right hand cued")
  248. elif Cues[first_set.thisN] == 1:# Left hand
  249. logging.data("Left hand cued")
  250. # -------Run Routine "trial"-------
  251. while continueRoutine and routineTimer.getTime() > 0:
  252. # get current time
  253. t = trialClock.getTime()
  254. tThisFlip = win.getFutureFlipTime(clock=trialClock)
  255. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  256. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  257. # update/draw components on each frame
  258. # *new_trial_text* updates
  259. if new_trial_text.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  260. trigport.setData(START_trig)
  261. core.wait(0.1)
  262. trigport.setData(0)
  263. # keep track of start time/frame for later
  264. new_trial_text.frameNStart = frameN # exact frame index
  265. new_trial_text.tStart = t # local t and not account for scr refresh
  266. new_trial_text.tStartRefresh = tThisFlipGlobal # on global time
  267. win.timeOnFlip(new_trial_text, 'tStartRefresh') # time at next scr refresh
  268. new_trial_text.setAutoDraw(True)
  269. if new_trial_text.status == STARTED:
  270. # is it time to stop? (based on local clock)
  271. if tThisFlip > 0.7-frameTolerance:
  272. # keep track of stop time/frame for later
  273. new_trial_text.tStop = t # not accounting for scr refresh
  274. new_trial_text.frameNStop = frameN # exact frame index
  275. win.timeOnFlip(new_trial_text, 'tStopRefresh') # time at next scr refresh
  276. new_trial_text.setAutoDraw(False)
  277. # *true_pattern* updates
  278. if true_pattern.status == NOT_STARTED and t >= 1-frameTolerance:
  279. # keep track of start time/frame for later
  280. true_pattern.frameNStart = frameN # exact frame index
  281. true_pattern.tStart = t # local t and not account for scr refresh
  282. true_pattern.tStartRefresh = tThisFlipGlobal # on global time
  283. win.timeOnFlip(true_pattern, 'tStartRefresh') # time at next scr refresh
  284. true_pattern.status = STARTED
  285. # win.callOnFlip(true_pattern.setData, int(1))
  286. if true_pattern.status == STARTED:
  287. # Send the true pattern
  288. seq = toBraille(pp[r,:],0)
  289. sendStim(seq,pattern1)
  290. trigport.setData(SAMPLE_trig)
  291. # is it time to stop? (based on global clock, using actual start)
  292. if tThisFlipGlobal > true_pattern.tStartRefresh + 0-frameTolerance:
  293. # keep track of stop time/frame for later
  294. true_pattern.tStop = t # not accounting for scr refresh
  295. true_pattern.frameNStop = frameN # exact frame index
  296. win.timeOnFlip(true_pattern, 'tStopRefresh') # time at next scr refresh
  297. true_pattern.status = FINISHED
  298. # win.callOnFlip(true_pattern.setData, int(0))
  299. # *cross* updates
  300. if cross.status == NOT_STARTED and tThisFlip >= 1-frameTolerance:
  301. # keep track of start time/frame for later
  302. cross.frameNStart = frameN # exact frame index
  303. cross.tStart = t # local t and not account for scr refresh
  304. cross.tStartRefresh = tThisFlipGlobal # on global time
  305. win.timeOnFlip(cross, 'tStartRefresh') # time at next scr refresh
  306. cross.setAutoDraw(True)
  307. if cross.status == STARTED:
  308. # is it time to stop? (based on local clock)
  309. if tThisFlip > 3-frameTolerance:
  310. # keep track of stop time/frame for later
  311. cross.tStop = t # not accounting for scr refresh
  312. cross.frameNStop = frameN # exact frame index
  313. win.timeOnFlip(cross, 'tStopRefresh') # time at next scr refresh
  314. cross.setAutoDraw(False)
  315. trigport.setData(0)
  316. sendStim(all_down,pattern1) # Put the pins down after 2 seconds
  317. if Cues[first_set.thisN] == 2: #Right hand hand
  318. # *cue_right* updates
  319. if cue_right.status == NOT_STARTED and tThisFlip >= 4-frameTolerance:
  320. # keep track of start time/frame for later
  321. cue_right.frameNStart = frameN # exact frame index
  322. cue_right.tStart = t # local t and not account for scr refresh
  323. cue_right.tStartRefresh = tThisFlipGlobal # on global time
  324. win.timeOnFlip(cue_right, 'tStartRefresh') # time at next scr refresh
  325. cue_right.setAutoDraw(True)
  326. trigport.setData(CUERIGHT_trig)
  327. if cue_right.status == STARTED:
  328. # is it time to stop? (based on local clock)
  329. if tThisFlip > 6-frameTolerance:
  330. # keep track of stop time/frame for later
  331. cue_right.tStop = t # not accounting for scr refresh
  332. cue_right.frameNStop = frameN # exact frame index
  333. win.timeOnFlip(cue_right, 'tStopRefresh') # time at next scr refresh
  334. cue_right.setAutoDraw(False)
  335. trigport.setData(0)
  336. elif Cues[first_set.thisN] ==1: #Left hand
  337. # *cue_left* updates
  338. if cue_left.status == NOT_STARTED and tThisFlip >= 4-frameTolerance:
  339. # keep track of start time/frame for later
  340. cue_left.frameNStart = frameN # exact frame index
  341. cue_left.tStart = t # local t and not account for scr refresh
  342. cue_left.tStartRefresh = tThisFlipGlobal # on global time
  343. win.timeOnFlip(cue_left, 'tStartRefresh') # time at next scr refresh
  344. cue_left.setAutoDraw(True)
  345. trigport.setData(CUELEFT_trig)
  346. if cue_left.status == STARTED:
  347. # is it time to stop? (based on local clock)
  348. if tThisFlip > 6-frameTolerance:
  349. # keep track of stop time/frame for later
  350. cue_left.tStop = t # not accounting for scr refresh
  351. cue_left.frameNStop = frameN # exact frame index
  352. win.timeOnFlip(cue_left, 'tStopRefresh') # time at next scr refresh
  353. cue_left.setAutoDraw(False)
  354. trigport.setData(0)
  355. # *pattern1* updates
  356. if pattern1.status == NOT_STARTED and t >= 7-frameTolerance:
  357. logging.data("Sending pattern 1")
  358. leftright = np.random.randint(1,3)
  359. logging.data("The trial number is ")
  360. if stimuli[0,0] == r and Cues[first_set.thisN] == leftright:
  361. logging.data("True pattern sent!")
  362. true_patterns_sent += 1
  363. trigport.setData(TRUE_trig)
  364. else:
  365. if leftright == 1:
  366. logging.data("False left")
  367. trigport.setData(FALSEL_trig)
  368. elif leftright == 2:
  369. logging.data("False right")
  370. trigport.setData(FALSER_trig)
  371. core.wait(0.01)
  372. trigport.setData(0)
  373. seq = toBraille(pp[stimuli[0,0],:],leftright)
  374. sendStim(seq,pattern1)
  375. # keep track of start time/frame for later
  376. pattern1.frameNStart = frameN # exact frame index
  377. pattern1.tStart = t # local t and not account for scr refresh
  378. pattern1.tStartRefresh = tThisFlipGlobal # on global time
  379. win.timeOnFlip(pattern1, 'tStartRefresh') # time at next scr refresh
  380. pattern1.status = STARTED
  381. # win.callOnFlip(pattern1.setData, int(1))
  382. if pattern1.status == STARTED:
  383. # is it time to stop? (based on global clock, using actual start)
  384. if tThisFlipGlobal > pattern1.tStartRefresh + 0.1-frameTolerance:
  385. # keep track of stop time/frame for later
  386. pattern1.tStop = t # not accounting for scr refresh
  387. pattern1.frameNStop = frameN # exact frame index
  388. win.timeOnFlip(pattern1, 'tStopRefresh') # time at next scr refresh
  389. pattern1.status = FINISHED
  390. sendStim(all_down,pattern1)
  391. # win.callOnFlip(pattern1.setData, int(0))
  392. # *button_resp1* updates
  393. waitOnFlip = False
  394. if button_resp1.status == NOT_STARTED and tThisFlip >= 7.1-frameTolerance:
  395. # keep track of start time/frame for later
  396. button_resp1.frameNStart = frameN # exact frame index
  397. button_resp1.tStart = t # local t and not account for scr refresh
  398. button_resp1.tStartRefresh = tThisFlipGlobal # on global time
  399. win.timeOnFlip(button_resp1, 'tStartRefresh') # time at next scr refresh
  400. button_resp1.status = STARTED
  401. # keyboard checking is just starting
  402. waitOnFlip = True
  403. win.callOnFlip(button_resp1.clock.reset) # t=0 on next screen flip
  404. win.callOnFlip(button_resp1.clearEvents, eventType='keyboard') # clear events on next screen flip
  405. if button_resp1.status == STARTED:
  406. # is it time to stop? (based on global clock, using actual start)
  407. if tThisFlipGlobal > button_resp1.tStartRefresh + 1-frameTolerance:
  408. # keep track of stop time/frame for later
  409. button_resp1.tStop = t # not accounting for scr refresh
  410. button_resp1.frameNStop = frameN # exact frame index
  411. win.timeOnFlip(button_resp1, 'tStopRefresh') # time at next scr refresh
  412. button_resp1.status = FINISHED
  413. if button_resp1.status == STARTED and not waitOnFlip:
  414. theseKeys = button_resp1.getKeys(keyList=['b', 'g', 'r', 'y'], waitRelease=False)
  415. _button_resp1_allKeys.extend(theseKeys)
  416. if len(_button_resp1_allKeys):
  417. button_resp1.keys = _button_resp1_allKeys[0].name # just the first key pressed
  418. totalpresses += 1
  419. if button_resp1.keys in left_keys:
  420. trigport.setData(LEFT_PRESS)
  421. logging.data("left press")
  422. if stimuli[0,0] == r and leftright == 1:
  423. correctpresses += 1
  424. elif button_resp1.keys in right_keys:
  425. trigport.setData(RIGHT_PRESS)
  426. logging.data("right press")
  427. if stimuli[0,0] == r and leftright == 2:
  428. correctpresses += 1
  429. core.wait(0.015)
  430. trigport.setData(0)
  431. button_resp1.rt = _button_resp1_allKeys[0].rt
  432. _button_resp1_allKeys = [] #Reset the list
  433. # *pattern2* updates
  434. if pattern2.status == NOT_STARTED and t >= 8.1-frameTolerance:
  435. logging.data("Sending pattern 2")
  436. leftright = np.random.randint(1,3)
  437. if stimuli[0,1] == r and Cues[first_set.thisN] == leftright:
  438. logging.data("True pattern sent!")
  439. true_patterns_sent += 1
  440. trigport.setData(TRUE_trig)
  441. else:
  442. if leftright == 1:
  443. logging.data("False left")
  444. trigport.setData(FALSEL_trig)
  445. elif leftright == 2:
  446. logging.data("False right")
  447. trigport.setData(FALSER_trig)
  448. core.wait(0.02)
  449. trigport.setData(0)
  450. seq = toBraille(pp[stimuli[0,1],:],leftright)
  451. sendStim(seq,pattern2)
  452. # keep track of start time/frame for later
  453. pattern2.frameNStart = frameN # exact frame index
  454. pattern2.tStart = t # local t and not account for scr refresh
  455. pattern2.tStartRefresh = tThisFlipGlobal # on global time
  456. win.timeOnFlip(pattern2, 'tStartRefresh') # time at next scr refresh
  457. pattern2.status = STARTED
  458. # win.callOnFlip(pattern2.setData, int(1))
  459. if pattern2.status == STARTED:
  460. # is it time to stop? (based on global clock, using actual start)
  461. if tThisFlipGlobal > pattern2.tStartRefresh + 0.1-frameTolerance:
  462. # keep track of stop time/frame for later
  463. pattern2.tStop = t # not accounting for scr refresh
  464. pattern2.frameNStop = frameN # exact frame index
  465. win.timeOnFlip(pattern2, 'tStopRefresh') # time at next scr refresh
  466. pattern2.status = FINISHED
  467. sendStim(all_down,pattern1)
  468. # win.callOnFlip(pattern2.setData, int(0))
  469. # *button_resp2* updates
  470. waitOnFlip = False
  471. if button_resp2.status == NOT_STARTED and tThisFlip >= 8.2-frameTolerance:
  472. # keep track of start time/frame for later
  473. button_resp2.frameNStart = frameN # exact frame index
  474. button_resp2.tStart = t # local t and not account for scr refresh
  475. button_resp2.tStartRefresh = tThisFlipGlobal # on global time
  476. win.timeOnFlip(button_resp2, 'tStartRefresh') # time at next scr refresh
  477. button_resp2.status = STARTED
  478. # keyboard checking is just starting
  479. waitOnFlip = True
  480. win.callOnFlip(button_resp2.clock.reset) # t=0 on next screen flip
  481. win.callOnFlip(button_resp2.clearEvents, eventType='keyboard') # clear events on next screen flip
  482. if button_resp2.status == STARTED:
  483. # is it time to stop? (based on global clock, using actual start)
  484. if tThisFlipGlobal > button_resp2.tStartRefresh + 1-frameTolerance:
  485. # keep track of stop time/frame for later
  486. button_resp2.tStop = t # not accounting for scr refresh
  487. button_resp2.frameNStop = frameN # exact frame index
  488. win.timeOnFlip(button_resp2, 'tStopRefresh') # time at next scr refresh
  489. button_resp2.status = FINISHED
  490. if button_resp2.status == STARTED and not waitOnFlip:
  491. theseKeys = button_resp2.getKeys(keyList=['b', 'g', 'r', 'y'], waitRelease=False)
  492. _button_resp2_allKeys.extend(theseKeys)
  493. if len(_button_resp2_allKeys):
  494. button_resp2.keys = _button_resp2_allKeys[0].name # just the first key pressed
  495. totalpresses += 1
  496. if button_resp2.keys in left_keys:
  497. trigport.setData(LEFT_PRESS)
  498. logging.data("left press")
  499. if stimuli[0,1] == r and leftright == 1:
  500. correctpresses += 1
  501. elif button_resp2.keys in right_keys:
  502. trigport.setData(RIGHT_PRESS)
  503. logging.data("right press")
  504. if stimuli[0,1] == r and leftright == 2:
  505. correctpresses += 1
  506. core.wait(0.015)
  507. trigport.setData(0)
  508. button_resp2.rt = _button_resp2_allKeys[0].rt
  509. _button_resp2_allKeys = [] # Reset the list
  510. # *pattern3* updates
  511. if pattern3.status == NOT_STARTED and t >= 9.2-frameTolerance:
  512. logging.data("Sending pattern 3")
  513. leftright = np.random.randint(1,3)
  514. if stimuli[0,2] == r and Cues[first_set.thisN] == leftright:
  515. logging.data("True pattern sent!")
  516. true_patterns_sent += 1
  517. trigport.setData(TRUE_trig)
  518. else:
  519. if leftright == 1:
  520. logging.data("False left")
  521. trigport.setData(FALSEL_trig)
  522. elif leftright == 2:
  523. logging.data("False right")
  524. trigport.setData(FALSER_trig)
  525. core.wait(0.02)
  526. trigport.setData(0)
  527. seq = toBraille(pp[stimuli[0,2],:],leftright)
  528. sendStim(seq,pattern3)
  529. # keep track of start time/frame for later
  530. pattern3.frameNStart = frameN # exact frame index
  531. pattern3.tStart = t # local t and not account for scr refresh
  532. pattern3.tStartRefresh = tThisFlipGlobal # on global time
  533. win.timeOnFlip(pattern3, 'tStartRefresh') # time at next scr refresh
  534. pattern3.status = STARTED
  535. # win.callOnFlip(pattern3.setData, int(1))
  536. if pattern3.status == STARTED:
  537. # is it time to stop? (based on global clock, using actual start)
  538. if tThisFlipGlobal > pattern3.tStartRefresh + 0.1-frameTolerance:
  539. # keep track of stop time/frame for later
  540. pattern3.tStop = t # not accounting for scr refresh
  541. pattern3.frameNStop = frameN # exact frame index
  542. win.timeOnFlip(pattern3, 'tStopRefresh') # time at next scr refresh
  543. pattern3.status = FINISHED
  544. sendStim(all_down,pattern1)
  545. # win.callOnFlip(pattern3.setData, int(0))
  546. # *button_resp3* updates
  547. waitOnFlip = False
  548. if button_resp3.status == NOT_STARTED and tThisFlip >= 9.3-frameTolerance:
  549. # keep track of start time/frame for later
  550. button_resp3.frameNStart = frameN # exact frame index
  551. button_resp3.tStart = t # local t and not account for scr refresh
  552. button_resp3.tStartRefresh = tThisFlipGlobal # on global time
  553. win.timeOnFlip(button_resp3, 'tStartRefresh') # time at next scr refresh
  554. button_resp3.status = STARTED
  555. # keyboard checking is just starting
  556. waitOnFlip = True
  557. win.callOnFlip(button_resp3.clock.reset) # t=0 on next screen flip
  558. win.callOnFlip(button_resp3.clearEvents, eventType='keyboard') # clear events on next screen flip
  559. if button_resp3.status == STARTED:
  560. # is it time to stop? (based on global clock, using actual start)
  561. if tThisFlipGlobal > button_resp3.tStartRefresh + 1-frameTolerance:
  562. # keep track of stop time/frame for later
  563. button_resp3.tStop = t # not accounting for scr refresh
  564. button_resp3.frameNStop = frameN # exact frame index
  565. win.timeOnFlip(button_resp3, 'tStopRefresh') # time at next scr refresh
  566. button_resp3.status = FINISHED
  567. if button_resp3.status == STARTED and not waitOnFlip:
  568. theseKeys = button_resp3.getKeys(keyList=['b', 'g', 'r', 'y'], waitRelease=False)
  569. _button_resp3_allKeys.extend(theseKeys)
  570. if len(_button_resp3_allKeys):
  571. button_resp3.keys = _button_resp3_allKeys[0].name # just the first key pressed
  572. totalpresses += 1
  573. if button_resp3.keys in left_keys:
  574. trigport.setData(LEFT_PRESS)
  575. logging.data("left press")
  576. if stimuli[0,2] == r and leftright == 1:
  577. correctpresses += 1
  578. elif button_resp3.keys in right_keys:
  579. trigport.setData(RIGHT_PRESS)
  580. logging.data("right press")
  581. if stimuli[0,2] == r and leftright == 2:
  582. correctpresses += 1
  583. core.wait(0.015)
  584. trigport.setData(0)
  585. button_resp3.rt = _button_resp3_allKeys[0].rt
  586. _button_resp3_allKeys = [] #Reset the list
  587. # *pattern4* updates
  588. if pattern4.status == NOT_STARTED and t >= 10.3-frameTolerance:
  589. logging.data("Sending pattern 4")
  590. leftright = np.random.randint(1,3)
  591. if stimuli[0,3] == r and Cues[first_set.thisN] == leftright:
  592. logging.data("True pattern sent!")
  593. true_patterns_sent += 1
  594. trigport.setData(TRUE_trig)
  595. else:
  596. if leftright == 1:
  597. logging.data("False left")
  598. trigport.setData(FALSEL_trig)
  599. elif leftright == 2:
  600. logging.data("False right")
  601. trigport.setData(FALSER_trig)
  602. core.wait(0.02)
  603. trigport.setData(0)
  604. seq = toBraille(pp[stimuli[0,3],:],leftright)
  605. sendStim(seq,pattern4)
  606. # keep track of start time/frame for later
  607. pattern4.frameNStart = frameN # exact frame index
  608. pattern4.tStart = t # local t and not account for scr refresh
  609. pattern4.tStartRefresh = tThisFlipGlobal # on global time
  610. win.timeOnFlip(pattern4, 'tStartRefresh') # time at next scr refresh
  611. pattern4.status = STARTED
  612. # win.callOnFlip(pattern4.setData, int(1))
  613. if pattern4.status == STARTED:
  614. # is it time to stop? (based on global clock, using actual start)
  615. if tThisFlipGlobal > pattern4.tStartRefresh + 0.1-frameTolerance:
  616. # keep track of stop time/frame for later
  617. pattern4.tStop = t # not accounting for scr refresh
  618. pattern4.frameNStop = frameN # exact frame index
  619. win.timeOnFlip(pattern4, 'tStopRefresh') # time at next scr refresh
  620. pattern4.status = FINISHED
  621. sendStim(all_down,pattern1)
  622. # win.callOnFlip(pattern4.setData, int(0))
  623. # *button_resp4* updates
  624. waitOnFlip = False
  625. if button_resp4.status == NOT_STARTED and tThisFlip >= 10.4-frameTolerance:
  626. # keep track of start time/frame for later
  627. button_resp4.frameNStart = frameN # exact frame index
  628. button_resp4.tStart = t # local t and not account for scr refresh
  629. button_resp4.tStartRefresh = tThisFlipGlobal # on global time
  630. win.timeOnFlip(button_resp4, 'tStartRefresh') # time at next scr refresh
  631. button_resp4.status = STARTED
  632. # keyboard checking is just starting
  633. waitOnFlip = True
  634. win.callOnFlip(button_resp4.clock.reset) # t=0 on next screen flip
  635. win.callOnFlip(button_resp4.clearEvents, eventType='keyboard') # clear events on next screen flip
  636. if button_resp4.status == STARTED:
  637. # is it time to stop? (based on global clock, using actual start)
  638. if tThisFlipGlobal > button_resp4.tStartRefresh + 1-frameTolerance:
  639. # keep track of stop time/frame for later
  640. button_resp4.tStop = t # not accounting for scr refresh
  641. button_resp4.frameNStop = frameN # exact frame index
  642. win.timeOnFlip(button_resp4, 'tStopRefresh') # time at next scr refresh
  643. button_resp4.status = FINISHED
  644. if button_resp4.status == STARTED and not waitOnFlip:
  645. theseKeys = button_resp4.getKeys(keyList=['b', 'g', 'r', 'y'], waitRelease=False)
  646. _button_resp4_allKeys.extend(theseKeys)
  647. if len(_button_resp4_allKeys):
  648. button_resp4.keys = _button_resp4_allKeys[0].name # just the first key pressed
  649. totalpresses += 1
  650. if button_resp4.keys in left_keys:
  651. trigport.setData(LEFT_PRESS)
  652. logging.data("left press")
  653. if stimuli[0,3] == r and leftright == 1:
  654. correctpresses += 1
  655. elif button_resp4.keys in right_keys:
  656. trigport.setData(RIGHT_PRESS)
  657. logging.data("right press")
  658. if stimuli[0,3] == r and leftright == 2:
  659. correctpresses += 1
  660. core.wait(0.015)
  661. trigport.setData(0)
  662. button_resp4.rt = _button_resp4_allKeys[0].rt
  663. _button_resp4_allKeys = [] #Reset the list
  664. # *pattern5* updates
  665. if pattern5.status == NOT_STARTED and t >= 11.4-frameTolerance:
  666. logging.data("Sending pattern 5")
  667. leftright = np.random.randint(1,3)
  668. if stimuli[0,4] == r and Cues[first_set.thisN] == leftright:
  669. logging.data("True pattern sent!")
  670. true_patterns_sent += 1
  671. trigport.setData(TRUE_trig)
  672. else:
  673. if leftright == 1:
  674. logging.data("False left")
  675. trigport.setData(FALSEL_trig)
  676. elif leftright == 2:
  677. logging.data("False right")
  678. trigport.setData(FALSER_trig)
  679. core.wait(0.02)
  680. trigport.setData(0)
  681. seq = toBraille(pp[stimuli[0,4],:],leftright)
  682. sendStim(seq,pattern5)
  683. # keep track of start time/frame for later
  684. pattern5.frameNStart = frameN # exact frame index
  685. pattern5.tStart = t # local t and not account for scr refresh
  686. pattern5.tStartRefresh = tThisFlipGlobal # on global time
  687. win.timeOnFlip(pattern5, 'tStartRefresh') # time at next scr refresh
  688. pattern5.status = STARTED
  689. # win.callOnFlip(pattern5.setData, int(1))
  690. if pattern5.status == STARTED:
  691. # is it time to stop? (based on global clock, using actual start)
  692. if tThisFlipGlobal > pattern5.tStartRefresh + 0.1-frameTolerance:
  693. # keep track of stop time/frame for later
  694. pattern5.tStop = t # not accounting for scr refresh
  695. pattern5.frameNStop = frameN # exact frame index
  696. win.timeOnFlip(pattern5, 'tStopRefresh') # time at next scr refresh
  697. pattern5.status = FINISHED
  698. sendStim(all_down,pattern1)
  699. # win.callOnFlip(pattern5.setData, int(0))
  700. # *button_resp5* updates
  701. waitOnFlip = False
  702. if button_resp5.status == NOT_STARTED and tThisFlip >= 11.5-frameTolerance:
  703. # keep track of start time/frame for later
  704. button_resp5.frameNStart = frameN # exact frame index
  705. button_resp5.tStart = t # local t and not account for scr refresh
  706. button_resp5.tStartRefresh = tThisFlipGlobal # on global time
  707. win.timeOnFlip(button_resp5, 'tStartRefresh') # time at next scr refresh
  708. button_resp5.status = STARTED
  709. # keyboard checking is just starting
  710. waitOnFlip = True
  711. win.callOnFlip(button_resp5.clock.reset) # t=0 on next screen flip
  712. win.callOnFlip(button_resp5.clearEvents, eventType='keyboard') # clear events on next screen flip
  713. if button_resp5.status == STARTED:
  714. # is it time to stop? (based on global clock, using actual start)
  715. if tThisFlipGlobal > button_resp5.tStartRefresh + 1-frameTolerance:
  716. # keep track of sexit()
  717. # op time/frame for later
  718. button_resp5.tStop = t # not accounting for scr refresh
  719. button_resp5.frameNStop = frameN # exact frame index
  720. win.timeOnFlip(button_resp5, 'tStopRefresh') # time at next scr refresh
  721. button_resp5.status = FINISHED
  722. if button_resp5.status == STARTED and not waitOnFlip:
  723. theseKeys = button_resp5.getKeys(keyList=['b', 'g', 'r', 'y'], waitRelease=False)
  724. _button_resp5_allKeys.extend(theseKeys)
  725. if len(_button_resp5_allKeys):
  726. button_resp5.keys = _button_resp5_allKeys[0].name # just the first key pressed
  727. totalpresses += 1
  728. if button_resp5.keys in left_keys:
  729. trigport.setData(LEFT_PRESS)
  730. logging.data("left press")
  731. if stimuli[0,4] == r and leftright == 1:
  732. correctpresses += 1
  733. elif button_resp5.keys in right_keys:
  734. trigport.setData(RIGHT_PRESS)
  735. logging.data("right press")
  736. if stimuli[0,4] == r and leftright == 2:
  737. correctpresses += 1
  738. core.wait(0.015)
  739. trigport.setData(0)
  740. button_resp5.rt = _button_resp5_allKeys[0].rt
  741. _button_resp5_allKeys = [] # Reset list
  742. # *cross2* updates
  743. if cross2.status == NOT_STARTED and tThisFlip >= 6-frameTolerance:
  744. # keep track of start time/frame for later
  745. cross2.frameNStart = frameN # exact frame index
  746. cross2.tStart = t # local t and not account for scr refresh
  747. cross2.tStartRefresh = tThisFlipGlobal # on global time
  748. win.timeOnFlip(cross2, 'tStartRefresh') # time at next scr refresh
  749. cross2.setAutoDraw(True)
  750. if cross2.status == STARTED:
  751. # is it time to stop? (based on local clock)
  752. if tThisFlip > 16-frameTolerance:
  753. # keep track of stop time/frame for later
  754. cross2.tStop = t # not accounting for scr refresh
  755. cross2.frameNStop = frameN # exact frame index
  756. win.timeOnFlip(cross2, 'tStopRefresh') # time at next scr refresh
  757. cross2.setAutoDraw(False)
  758. # check for quit (typically the Esc key)
  759. if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
  760. core.quit()
  761. # check if all components have finished
  762. if not continueRoutine: # a component has requested a forced-end of Routine
  763. break
  764. continueRoutine = False # will revert to True if at least one component still running
  765. for thisComponent in trialComponents:
  766. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  767. continueRoutine = True
  768. break # at least one component has not yet finished
  769. # refresh the screen
  770. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  771. win.flip()
  772. # -------Ending Routine "trial"-------
  773. for thisComponent in trialComponents:
  774. if hasattr(thisComponent, "setAutoDraw"):
  775. thisComponent.setAutoDraw(False)
  776. first_set.addData('new_trial_text.started', new_trial_text.tStartRefresh)
  777. first_set.addData('new_trial_text.stopped', new_trial_text.tStopRefresh)
  778. if true_pattern.status == STARTED:
  779. win.callOnFlip(true_pattern.setData, int(0))
  780. first_set.addData('true_pattern.started', true_pattern.tStart)
  781. first_set.addData('true_pattern.stopped', true_pattern.tStop)
  782. first_set.addData('cross.started', cross.tStartRefresh)
  783. first_set.addData('cross.stopped', cross.tStopRefresh)
  784. first_set.addData('cue_right.started', cue_right.tStartRefresh)
  785. first_set.addData('cue_right.stopped', cue_right.tStopRefresh)
  786. first_set.addData('cue_left.started', cue_left.tStartRefresh)
  787. first_set.addData('cue_left.stopped', cue_left.tStopRefresh)
  788. if pattern1.status == STARTED:
  789. win.callOnFlip(pattern1.setData, int(0))
  790. first_set.addData('pattern1.started', pattern1.tStart)
  791. first_set.addData('pattern1.stopped', pattern1.tStop)
  792. # check responses
  793. if button_resp1.keys in ['', [], None]: # No response was made
  794. button_resp1.keys = None
  795. first_set.addData('button_resp1.keys',button_resp1.keys)
  796. if button_resp1.keys != None: # we had a response
  797. first_set.addData('button_resp1.rt', button_resp1.rt)
  798. first_set.addData('button_resp1.started', button_resp1.tStartRefresh)
  799. first_set.addData('button_resp1.stopped', button_resp1.tStopRefresh)
  800. if pattern2.status == STARTED:
  801. win.callOnFlip(pattern2.setData, int(0))
  802. first_set.addData('pattern2.started', pattern2.tStart)
  803. first_set.addData('pattern2.stopped', pattern2.tStop)
  804. # check responses
  805. if button_resp2.keys in ['', [], None]: # No response was made
  806. button_resp2.keys = None
  807. first_set.addData('button_resp2.keys',button_resp2.keys)
  808. if button_resp2.keys != None: # we had a response
  809. first_set.addData('button_resp2.rt', button_resp2.rt)
  810. first_set.addData('button_resp2.started', button_resp2.tStartRefresh)
  811. first_set.addData('button_resp2.stopped', button_resp2.tStopRefresh)
  812. if pattern3.status == STARTED:
  813. win.callOnFlip(pattern3.setData, int(0))
  814. first_set.addData('pattern3.started', pattern3.tStart)
  815. first_set.addData('pattern3.stopped', pattern3.tStop)
  816. # check responses
  817. if button_resp3.keys in ['', [], None]: # No response was made
  818. button_resp3.keys = None
  819. first_set.addData('button_resp3.keys',button_resp3.keys)
  820. if button_resp3.keys != None: # we had a response
  821. first_set.addData('button_resp3.rt', button_resp3.rt)
  822. first_set.addData('button_resp3.started', button_resp3.tStartRefresh)
  823. first_set.addData('button_resp3.stopped', button_resp3.tStopRefresh)
  824. if pattern4.status == STARTED:
  825. win.callOnFlip(pattern4.setData, int(0))
  826. first_set.addData('pattern4.started', pattern4.tStart)
  827. first_set.addData('pattern4.stopped', pattern4.tStop)
  828. # check responses
  829. if button_resp4.keys in ['', [], None]: # No response was made
  830. button_resp4.keys = None
  831. first_set.addData('button_resp4.keys',button_resp4.keys)
  832. if button_resp4.keys != None: # we had a response
  833. first_set.addData('button_resp4.rt', button_resp4.rt)
  834. first_set.addData('button_resp4.started', button_resp4.tStartRefresh)
  835. first_set.addData('button_resp4.stopped', button_resp4.tStopRefresh)
  836. if pattern5.status == STARTED:
  837. win.callOnFlip(pattern5.setData, int(0))
  838. first_set.addData('pattern5.started', pattern5.tStart)
  839. first_set.addData('pattern5.stopped', pattern5.tStop)
  840. # check responses
  841. if button_resp5.keys in ['', [], None]: # No response was made
  842. button_resp5.keys = None
  843. first_set.addData('button_resp5.keys',button_resp5.keys)
  844. if button_resp5.keys != None: # we had a response
  845. first_set.addData('button_resp5.rt', button_resp5.rt)
  846. first_set.addData('button_resp5.started', button_resp5.tStartRefresh)
  847. first_set.addData('button_resp5.stopped', button_resp5.tStopRefresh)
  848. first_set.addData('cross2.started', cross2.tStartRefresh)
  849. first_set.addData('cross2.stopped', cross2.tStopRefresh)
  850. thisExp.nextEntry()
  851. # completed 10.0 repeats of 'first_set'
  852. # ------Prepare to start Routine "feedback"-------
  853. continueRoutine = True
  854. routineTimer.add(16.000000)
  855. # update component parameters for each repeat
  856. # keep track of which components have finished
  857. feedbackComponents = [feedback_string]
  858. for thisComponent in feedbackComponents:
  859. thisComponent.tStart = None
  860. thisComponent.tStop = None
  861. thisComponent.tStartRefresh = None
  862. thisComponent.tStopRefresh = None
  863. if hasattr(thisComponent, 'status'):
  864. thisComponent.status = NOT_STARTED
  865. # reset timers
  866. t = 0
  867. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  868. feedbackClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip
  869. frameN = -1
  870. # -------Run Routine "feedback"-------
  871. while continueRoutine and routineTimer.getTime() > 0:
  872. # get current time
  873. t = feedbackClock.getTime()
  874. tThisFlip = win.getFutureFlipTime(clock=feedbackClock)
  875. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  876. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  877. # update/draw components on each frame
  878. # *feedback_string* updates
  879. if feedback_string.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  880. # keep track of start time/frame for later
  881. feedback_string.frameNStart = frameN # exact frame index
  882. feedback_string.tStart = t # local t and not account for scr refresh
  883. feedback_string.tStartRefresh = tThisFlipGlobal # on global time
  884. feedback_string.text = "Total button presses {} \n You got {} out {} true patterns sent".format(totalpresses, correctpresses, true_patterns_sent)
  885. win.timeOnFlip(feedback_string, 'tStartRefresh') # time at next scr refresh
  886. feedback_string.setAutoDraw(True)
  887. if feedback_string.status == STARTED:
  888. # is it time to stop? (based on global clock, using actual start)
  889. if tThisFlipGlobal > feedback_string.tStartRefresh + 16-frameTolerance:
  890. # keep track of stop time/frame for later
  891. feedback_string.tStop = t # not accounting for scr refresh
  892. feedback_string.frameNStop = frameN # exact frame index
  893. win.timeOnFlip(feedback_string, 'tStopRefresh') # time at next scr refresh
  894. feedback_string.setAutoDraw(False)
  895. # check for quit (typically the Esc key)
  896. if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
  897. core.quit()
  898. # check if all components have finished
  899. if not continueRoutine: # a component has requested a forced-end of Routine
  900. break
  901. continueRoutine = False # will revert to True if at least one component still running
  902. for thisComponent in feedbackComponents:
  903. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  904. continueRoutine = True
  905. break # at least one component has not yet finished
  906. # refresh the screen
  907. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  908. win.flip()
  909. # -------Ending Routine "feedback"-------
  910. for thisComponent in feedbackComponents:
  911. if hasattr(thisComponent, "setAutoDraw"):
  912. thisComponent.setAutoDraw(False)
  913. Paradigm.addData('feedback_string.started', feedback_string.tStartRefresh)
  914. Paradigm.addData('feedback_string.stopped', feedback_string.tStopRefresh)
  915. thisExp.nextEntry()
  916. #Reset counters
  917. totalpresses = 0
  918. true_patterns_sent = 0
  919. correctpresses = 0
  920. # completed 8.0 repeats of 'Paradigm'
  921. # Flip one final time so any remaining win.callOnFlip()
  922. # and win.timeOnFlip() tasks get executed before quitting
  923. win.flip()
  924. # these shouldn't be strictly necessary (should auto-save)
  925. thisExp.saveAsWideText(filename+'.csv', delim='auto')
  926. thisExp.saveAsPickle(filename)
  927. logging.flush()
  928. # Write paradigm data to json file
  929. All_Cues = np.concatenate(AttendHand, axis = 0)
  930. np.savetxt("All_Cues.csv", All_Cues, delimiter=",")
  931. true_pattern_chosen = np.concatenate(true_pattern_chosen)
  932. np.savetxt("true_patterns_chose.csv", true_pattern_chosen, delimiter=",")
  933. All_patterns_sent = np.concatenate(patterns, axis =0)
  934. np.savetxt("All_patterns_sent.csv", All_patterns_sent, delimiter=",")
  935. # make sure everything is closed down
  936. thisExp.abort() # or data files will save again on exit
  937. win.close()
  938. core.quit()

Toolbox_killer.py at commit 10262ac, no license · at the source

Overview

Authors: Gonzalo Reina Rivero1,2, Zoe Tanner1,2, Lukas Rier1, Ryan M Hill1, Vishal Shah3, Molly Rea2, Cody Doyle3, James Osborne3, David Bobela3, Peter G Morris1, Karen J Mullinger1,4, Elena Boto1,2, Niall Holmes1,2, Matthew J Brookes1,2
  1. Sir Peter Mansfield Imaging Centre, School of Physics and Astronomy, University of Nottingham, University Park, Nottingham, NG7 2RD UK
  2. Cerca Magnetics Limited, 2 Castlebridge Office Village, Kirtley Drive, Nottingham, NG7 1LD UK
  3. QuSpin Inc., 331 South 104th Street, Suite 130, Louisville, CO 80027 USA
  4. Centre for Human Brain Health, School of Psychology, University of Birmingham, Birmingham, B15 2TT UK
Institutions: University of Nottingham (United Kingdom); QuSpin (United States) (United States); University of Birmingham (United Kingdom)
Journal: n/a, volume 15, issue 1, article 30471
Dates: received 25 April 2024; accepted 18 June 2025; published online 19 August 2025
Type: Research article · Language: English
License: none stated
Identifiers: DOI 10.1038/s41598-025-08037-8 · PMCID PMC12365038 · OpenAlex W4413316870
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: EEG (modality), MEG (modality), human (organism)
Methods: Spectral & time-frequency, Statistics, Preprocessing, fMRI & imaging
Keywords: Beta oscillations, Bursts, Somatosensory, Inhibition, optically pumped magnetometers, Magnetoencephalography, MEG, Attention, Biological physics
MeSH: Attention*, Beta Rhythm*, Magnetoencephalography*, Somatosensory Cortex*, Adult, Electroencephalography, Female, Humans, Male, Young Adult (* major topic)
Topic: Neural dynamics and brain function (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: EPSRC (EP/V047264/1)
Citations: cited by 3 papers (Europe PMC); 81 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (none stated) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repository

Its files are read in the Code ↔ Paper reader above.

GonReina/Braille_paradigm

License: none: the authors keep all their rights
State: the link answers, verified on 26 September 2026
Evidence: files inventoried
Commit: 10262acb01aed8488beee5491662ca23c4090514, 28 March 2023
Languages: Python (5)
Size: 14 files, 5 scripts
Software Heritage: not archived
Found in: the text, “Tactile attention paradigm”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: PsychoPy (4 files), NumPy (3 files)
Availability: 1 check, the latest on 26 September 2026: the link answers
  • 26 September 2026: the link answers
6 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 5 scripts, each with its path and the digest of its content;
  • no match between paragraphs and code yet;
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Code and data availability statement

The paper has a code and data availability statement. Its license (none stated) does not allow reproducing it here; in short, from what the harvester recognized in it:

  • it says that the data are available on request
  • it says that the code is available on request

Read it in the paper: doi.org/10.1038/s41598-025-08037-8.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 14 authors, 9 keywords, 10 MeSH terms, 1 funder, 72 references.

Cite

This paper

Rivero, G. R., Tanner, Z., Rier, L., Hill, R. M., Shah, V., Rea, M., Doyle, C., Osborne, J., Bobela, D., Morris, P. G., Mullinger, K. J., Boto, E., Holmes, N., & Brookes, M. J. (2025). OPM-MEG reveals dynamics of beta bursts underlying attentional processes in sensory cortex. Scientific Reports, 15(1), 30471. https://doi.org/10.1038/s41598-025-08037-8

BibTeX

@article{rivero2025opm,
author = {Rivero, Gonzalo Reina and Tanner, Zoe and Rier, Lukas and Hill, Ryan M and Shah, Vishal and Rea, Molly and Doyle, Cody and Osborne, James and Bobela, David and Morris, Peter G and Mullinger, Karen J and Boto, Elena and Holmes, Niall and Brookes, Matthew J},
title = {{OPM-MEG reveals dynamics of beta bursts underlying attentional processes in sensory cortex}},
journal = {Scientific Reports},
year = {2025},
volume = {15},
number = {1},
pages = {30471},
publisher = {Nature Publishing Group},
issn = {2045-2322},
doi = {10.1038/s41598-025-08037-8},
url = {https://doi.org/10.1038/s41598-025-08037-8},
pmcid = {PMC12365038}
}

RIS

TY - JOUR
AU - Rivero, Gonzalo Reina
AU - Tanner, Zoe
AU - Rier, Lukas
AU - Hill, Ryan M
AU - Shah, Vishal
AU - Rea, Molly
AU - Doyle, Cody
AU - Osborne, James
AU - Bobela, David
AU - Morris, Peter G
AU - Mullinger, Karen J
AU - Boto, Elena
AU - Holmes, Niall
AU - Brookes, Matthew J
TI - OPM-MEG reveals dynamics of beta bursts underlying attentional processes in sensory cortex
T2 - Scientific Reports
J2 - Sci Rep
PY - 2025
DA - 2025
VL - 15
IS - 1
SP - 30471
SN - 2045-2322
PB - Nature Publishing Group
DO - 10.1038/s41598-025-08037-8
UR - https://doi.org/10.1038/s41598-025-08037-8
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41598-025-08037-8",
"type": "article-journal",
"title": "OPM-MEG reveals dynamics of beta bursts underlying attentional processes in sensory cortex",
"container-title": "Scientific Reports",
"author": [
{
"family": "Rivero",
"given": "Gonzalo Reina"
},
{
"family": "Tanner",
"given": "Zoe"
},
{
"family": "Rier",
"given": "Lukas"
},
{
"family": "Hill",
"given": "Ryan M"
},
{
"family": "Shah",
"given": "Vishal"
},
{
"family": "Rea",
"given": "Molly"
},
{
"family": "Doyle",
"given": "Cody"
},
{
"family": "Osborne",
"given": "James"
},
{
"family": "Bobela",
"given": "David"
},
{
"family": "Morris",
"given": "Peter G"
},
{
"family": "Mullinger",
"given": "Karen J"
},
{
"family": "Boto",
"given": "Elena"
},
{
"family": "Holmes",
"given": "Niall"
},
{
"family": "Brookes",
"given": "Matthew J"
}
],
"container-title-short": "Sci Rep",
"volume": "15",
"issue": "1",
"page": "30471",
"DOI": "10.1038/s41598-025-08037-8",
"PMCID": "PMC12365038",
"ISSN": "2045-2322",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41598-025-08037-8",
"language": "en",
"issued": {
"date-parts": [
[
2025
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1162/imag.a.1040 [code]
Novel 4 He-OPMs support waveform-specific beta burst analysis comparable to SQUID-MEG
Journal: n/a
In common: NumPy, MEG, 14 references
[2] doi:10.1162/imag.a.1218 [code]
Reliability and signal comparison of OPM-MEG, fMRI & iEEG in a repeated movie viewing paradigm.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: MEG, 12 references
[3] doi:10.3390/s26103131 [code]
Neuromagnetism "On the Cheap": Evaluating a Combined Cylindrical Shield and Partial-Coverage OPM-MEG System for Detecting Sensorimotor Responses in Humans.
Journal: Sensors (Basel, Switzerland)
In common: NumPy, MEG, 8 references
[4] doi:10.64898/2026.03.06.710026 [code]
Distinct beta burst motifs exhibit opposing error relationships during motor adaptation
Journal: bioRxiv (preprint)
In common: NumPy, 9 references
[5] doi:10.1007/s10548-025-01150-x
Movement Related Beta-Band Modulation with OPM-MEG: A Pilot Study
Journal: n/a
In common: MEG, 8 references
[6] doi:10.1016/j.isci.2025.113806 [code]
Beta-band frequency shifts signal decisions in human prefrontal cortex
Journal: n/a
In common: 9 references
[7] doi:10.1016/j.neuroimage.2026.121930
Quantifying cerebellar signal detectability in MEG and EEG in epilepsy using anatomically informed source modeling.
Journal: NeuroImage
In common: MEG, EEG, 7 references
[8] doi:10.1162/imag.a.1226 [code]
A neuroscientist's guide to neural burst detection.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: NumPy, 8 references
[9] doi:10.1111/psyp.70345 [code]
sBOSC: A Method for Source-Level Identification of Neural Oscillations in Electromagnetic Brain Signals.
Journal: Psychophysiology
In common: MEG, EEG, 8 references
[10] doi:10.1038/s41467-026-73553-8 [code]
Universal rhythmic architecture uncovers two modes of neural dynamics.
Journal: Nature communications
In common: NumPy, EEG, 7 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.