OSCR

<i>From concept to proof:</i> developing a neurofeedback-fNIRS protocol to train self-regulation for music performance anxiety in adolescent musicians.

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 · 1,881 lines · 77 KB · no license

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This experiment was created using PsychoPy3 Experiment Builder (v2024.2.4),
  5. on June 11, 2025, at 16:41
  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. # --- Import packages ---
  12. from psychopy import locale_setup
  13. from psychopy import prefs
  14. from psychopy import plugins
  15. plugins.activatePlugins()
  16. prefs.hardware['audioLib'] = 'ptb'
  17. prefs.hardware['audioLatencyMode'] = '3'
  18. from psychopy import sound, gui, visual, core, data, event, logging, clock, colors, layout, hardware
  19. from psychopy.tools import environmenttools
  20. from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
  21. STOPPED, FINISHED, PRESSED, RELEASED, FOREVER, priority)
  22. import numpy as np # whole numpy lib is available, prepend 'np.'
  23. from numpy import (sin, cos, tan, log, log10, pi, average,
  24. sqrt, std, deg2rad, rad2deg, linspace, asarray)
  25. from numpy.random import random, randint, normal, shuffle, choice as randchoice
  26. import os # handy system and path functions
  27. import sys # to get file system encoding
  28. import psychopy.iohub as io
  29. from psychopy.hardware import keyboard
  30. # Run 'Before Experiment' code from code
  31. import random
  32. from pylsl import StreamInfo, StreamOutlet # import required classes
  33. situations = {
  34. "Situation1": './BIN/Recordings/Situation1/',
  35. "Situation2": './BIN/Recordings/Situation2/',
  36. "Situation3": './BIN/Recordings/Situation3/',
  37. "Situation4": './BIN/Recordings/Situation4/',
  38. "Situation5": './BIN/Recordings/Situation5/',
  39. "Situation6": './BIN/Recordings/Situation6/',
  40. "Situation7": './BIN/Recordings/Situation7/',
  41. "Situation8": './BIN/Recordings/Situation8/',
  42. "Situation9": './BIN/Recordings/Situation9/',
  43. "Situation10": './BIN/Recordings/Situation10/',
  44. "Situation11": './BIN/Recordings/Situation11/',
  45. "Situation12": './BIN/Recordings/Situation12/',
  46. "Situation13": './BIN/Recordings/Situation13/',
  47. "Situation14": './BIN/Recordings/Situation14/',
  48. "Situation15": './BIN/Recordings/Situation15/',
  49. "Situation16": './BIN/Recordings/Situation16/',
  50. "Situation17": './BIN/Recordings/Situation17/',
  51. "Situation18": './BIN/Recordings/Situation18/',
  52. "Situation19": './BIN/Recordings/Situation19/'
  53. }
  54. iteration = 0
  55. iteration_ctr = 0
  56. ctr_lst = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]
  57. str_lst = [1,2,3,4,5]
  58. # Run 'Before Experiment' code from code_7
  59. import time
  60. # --- Setup global variables (available in all functions) ---
  61. # create a device manager to handle hardware (keyboards, mice, mirophones, speakers, etc.)
  62. deviceManager = hardware.DeviceManager()
  63. # ensure that relative paths start from the same directory as this script
  64. _thisDir = os.path.dirname(os.path.abspath(__file__))
  65. # store info about the experiment session
  66. psychopyVersion = '2024.2.4'
  67. expName = 'Model of training' # from the Builder filename that created this script
  68. # information about this experiment
  69. expInfo = {
  70. 'participant': f"{randint(0, 999999):06.0f}",
  71. 'session': '001',
  72. 'Situation': '',
  73. 'date|hid': data.getDateStr(),
  74. 'expName|hid': expName,
  75. 'psychopyVersion|hid': psychopyVersion,
  76. }
  77. # --- Define some variables which will change depending on pilot mode ---
  78. '''
  79. To run in pilot mode, either use the run/pilot toggle in Builder, Coder and Runner,
  80. or run the experiment with `--pilot` as an argument. To change what pilot
  81. #mode does, check out the 'Pilot mode' tab in preferences.
  82. '''
  83. # work out from system args whether we are running in pilot mode
  84. PILOTING = core.setPilotModeFromArgs()
  85. # start off with values from experiment settings
  86. _fullScr = False
  87. _winSize = [800, 900]
  88. # if in pilot mode, apply overrides according to preferences
  89. if PILOTING:
  90. # force windowed mode
  91. if prefs.piloting['forceWindowed']:
  92. _fullScr = False
  93. # set window size
  94. _winSize = prefs.piloting['forcedWindowSize']
  95. def showExpInfoDlg(expInfo):
  96. """
  97. Show participant info dialog.
  98. Parameters
  99. ==========
  100. expInfo : dict
  101. Information about this experiment.
  102. Returns
  103. ==========
  104. dict
  105. Information about this experiment.
  106. """
  107. # show participant info dialog
  108. dlg = gui.DlgFromDict(
  109. dictionary=expInfo, sortKeys=False, title=expName, alwaysOnTop=True
  110. )
  111. if dlg.OK == False:
  112. core.quit() # user pressed cancel
  113. # return expInfo
  114. return expInfo
  115. def setupData(expInfo, dataDir=None):
  116. """
  117. Make an ExperimentHandler to handle trials and saving.
  118. Parameters
  119. ==========
  120. expInfo : dict
  121. Information about this experiment, created by the `setupExpInfo` function.
  122. dataDir : Path, str or None
  123. Folder to save the data to, leave as None to create a folder in the current directory.
  124. Returns
  125. ==========
  126. psychopy.data.ExperimentHandler
  127. Handler object for this experiment, contains the data to save and information about
  128. where to save it to.
  129. """
  130. # remove dialog-specific syntax from expInfo
  131. for key, val in expInfo.copy().items():
  132. newKey, _ = data.utils.parsePipeSyntax(key)
  133. expInfo[newKey] = expInfo.pop(key)
  134. # data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
  135. if dataDir is None:
  136. dataDir = _thisDir
  137. filename = u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
  138. # make sure filename is relative to dataDir
  139. if os.path.isabs(filename):
  140. dataDir = os.path.commonprefix([dataDir, filename])
  141. filename = os.path.relpath(filename, dataDir)
  142. # an ExperimentHandler isn't essential but helps with data saving
  143. thisExp = data.ExperimentHandler(
  144. name=expName, version='',
  145. extraInfo=expInfo, runtimeInfo=None,
  146. originPath='C:\\Users\\User\\Desktop\\Musa\\Musa - Protocolo Pedro\\Model of training_lastrun.py',
  147. savePickle=True, saveWideText=True,
  148. dataFileName=dataDir + os.sep + filename, sortColumns='time'
  149. )
  150. thisExp.setPriority('thisRow.t', priority.CRITICAL)
  151. thisExp.setPriority('expName', priority.LOW)
  152. # return experiment handler
  153. return thisExp
  154. def setupLogging(filename):
  155. """
  156. Setup a log file and tell it what level to log at.
  157. Parameters
  158. ==========
  159. filename : str or pathlib.Path
  160. Filename to save log file and data files as, doesn't need an extension.
  161. Returns
  162. ==========
  163. psychopy.logging.LogFile
  164. Text stream to receive inputs from the logging system.
  165. """
  166. # set how much information should be printed to the console / app
  167. if PILOTING:
  168. logging.console.setLevel(
  169. prefs.piloting['pilotConsoleLoggingLevel']
  170. )
  171. else:
  172. logging.console.setLevel('warning')
  173. # save a log file for detail verbose info
  174. logFile = logging.LogFile(filename+'.log')
  175. if PILOTING:
  176. logFile.setLevel(
  177. prefs.piloting['pilotLoggingLevel']
  178. )
  179. else:
  180. logFile.setLevel(
  181. logging.getLevel('info')
  182. )
  183. return logFile
  184. def setupWindow(expInfo=None, win=None):
  185. """
  186. Setup the Window
  187. Parameters
  188. ==========
  189. expInfo : dict
  190. Information about this experiment, created by the `setupExpInfo` function.
  191. win : psychopy.visual.Window
  192. Window to setup - leave as None to create a new window.
  193. Returns
  194. ==========
  195. psychopy.visual.Window
  196. Window in which to run this experiment.
  197. """
  198. if win is None:
  199. # if not given a window to setup, make one
  200. win = visual.Window(
  201. size=_winSize, fullscr=_fullScr, screen=0,
  202. winType='pyglet', allowGUI=True, allowStencil=False,
  203. monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
  204. backgroundImage='', backgroundFit='none',
  205. blendMode='avg', useFBO=True,
  206. units='height',
  207. checkTiming=False # we're going to do this ourselves in a moment
  208. )
  209. else:
  210. # if we have a window, just set the attributes which are safe to set
  211. win.color = [0,0,0]
  212. win.colorSpace = 'rgb'
  213. win.backgroundImage = ''
  214. win.backgroundFit = 'none'
  215. win.units = 'height'
  216. if expInfo is not None:
  217. # get/measure frame rate if not already in expInfo
  218. if win._monitorFrameRate is None:
  219. win._monitorFrameRate = win.getActualFrameRate(infoMsg='Attempting to measure frame rate of screen, please wait...')
  220. expInfo['frameRate'] = win._monitorFrameRate
  221. win.hideMessage()
  222. # show a visual indicator if we're in piloting mode
  223. if PILOTING and prefs.piloting['showPilotingIndicator']:
  224. win.showPilotingIndicator()
  225. return win
  226. def setupDevices(expInfo, thisExp, win):
  227. """
  228. Setup whatever devices are available (mouse, keyboard, speaker, eyetracker, etc.) and add them to
  229. the device manager (deviceManager)
  230. Parameters
  231. ==========
  232. expInfo : dict
  233. Information about this experiment, created by the `setupExpInfo` function.
  234. thisExp : psychopy.data.ExperimentHandler
  235. Handler object for this experiment, contains the data to save and information about
  236. where to save it to.
  237. win : psychopy.visual.Window
  238. Window in which to run this experiment.
  239. Returns
  240. ==========
  241. bool
  242. True if completed successfully.
  243. """
  244. # --- Setup input devices ---
  245. ioConfig = {}
  246. # Setup iohub keyboard
  247. ioConfig['Keyboard'] = dict(use_keymap='psychopy')
  248. # Setup iohub experiment
  249. ioConfig['Experiment'] = dict(filename=thisExp.dataFileName)
  250. # Start ioHub server
  251. ioServer = io.launchHubServer(window=win, **ioConfig)
  252. # store ioServer object in the device manager
  253. deviceManager.ioServer = ioServer
  254. # create a default keyboard (e.g. to check for escape)
  255. if deviceManager.getDevice('defaultKeyboard') is None:
  256. deviceManager.addDevice(
  257. deviceClass='keyboard', deviceName='defaultKeyboard', backend='iohub'
  258. )
  259. if deviceManager.getDevice('key_resp') is None:
  260. # initialise key_resp
  261. key_resp = deviceManager.addDevice(
  262. deviceClass='keyboard',
  263. deviceName='key_resp',
  264. )
  265. # create speaker 'sound_1'
  266. deviceManager.addDevice(
  267. deviceName='sound_1',
  268. deviceClass='psychopy.hardware.speaker.SpeakerDevice',
  269. index=-1
  270. )
  271. # create speaker 'sound_2'
  272. deviceManager.addDevice(
  273. deviceName='sound_2',
  274. deviceClass='psychopy.hardware.speaker.SpeakerDevice',
  275. index=-1
  276. )
  277. # create speaker 'sound_3'
  278. deviceManager.addDevice(
  279. deviceName='sound_3',
  280. deviceClass='psychopy.hardware.speaker.SpeakerDevice',
  281. index=-1
  282. )
  283. # return True if completed successfully
  284. return True
  285. def pauseExperiment(thisExp, win=None, timers=[], playbackComponents=[]):
  286. """
  287. Pause this experiment, preventing the flow from advancing to the next routine until resumed.
  288. Parameters
  289. ==========
  290. thisExp : psychopy.data.ExperimentHandler
  291. Handler object for this experiment, contains the data to save and information about
  292. where to save it to.
  293. win : psychopy.visual.Window
  294. Window for this experiment.
  295. timers : list, tuple
  296. List of timers to reset once pausing is finished.
  297. playbackComponents : list, tuple
  298. List of any components with a `pause` method which need to be paused.
  299. """
  300. # if we are not paused, do nothing
  301. if thisExp.status != PAUSED:
  302. return
  303. # start a timer to figure out how long we're paused for
  304. pauseTimer = core.Clock()
  305. # pause any playback components
  306. for comp in playbackComponents:
  307. comp.pause()
  308. # make sure we have a keyboard
  309. defaultKeyboard = deviceManager.getDevice('defaultKeyboard')
  310. if defaultKeyboard is None:
  311. defaultKeyboard = deviceManager.addKeyboard(
  312. deviceClass='keyboard',
  313. deviceName='defaultKeyboard',
  314. backend='ioHub',
  315. )
  316. # run a while loop while we wait to unpause
  317. while thisExp.status == PAUSED:
  318. # check for quit (typically the Esc key)
  319. if defaultKeyboard.getKeys(keyList=['escape']):
  320. endExperiment(thisExp, win=win)
  321. # sleep 1ms so other threads can execute
  322. clock.time.sleep(0.001)
  323. # if stop was requested while paused, quit
  324. if thisExp.status == FINISHED:
  325. endExperiment(thisExp, win=win)
  326. # resume any playback components
  327. for comp in playbackComponents:
  328. comp.play()
  329. # reset any timers
  330. for timer in timers:
  331. timer.addTime(-pauseTimer.getTime())
  332. def run(expInfo, thisExp, win, globalClock=None, thisSession=None):
  333. """
  334. Run the experiment flow.
  335. Parameters
  336. ==========
  337. expInfo : dict
  338. Information about this experiment, created by the `setupExpInfo` function.
  339. thisExp : psychopy.data.ExperimentHandler
  340. Handler object for this experiment, contains the data to save and information about
  341. where to save it to.
  342. psychopy.visual.Window
  343. Window in which to run this experiment.
  344. globalClock : psychopy.core.clock.Clock or None
  345. Clock to get global time from - supply None to make a new one.
  346. thisSession : psychopy.session.Session or None
  347. Handle of the Session object this experiment is being run from, if any.
  348. """
  349. # mark experiment as started
  350. thisExp.status = STARTED
  351. # make sure window is set to foreground to prevent losing focus
  352. win.winHandle.activate()
  353. # make sure variables created by exec are available globally
  354. exec = environmenttools.setExecEnvironment(globals())
  355. # get device handles from dict of input devices
  356. ioServer = deviceManager.ioServer
  357. # get/create a default keyboard (e.g. to check for escape)
  358. defaultKeyboard = deviceManager.getDevice('defaultKeyboard')
  359. if defaultKeyboard is None:
  360. deviceManager.addDevice(
  361. deviceClass='keyboard', deviceName='defaultKeyboard', backend='ioHub'
  362. )
  363. eyetracker = deviceManager.getDevice('eyetracker')
  364. # make sure we're running in the directory for this experiment
  365. os.chdir(_thisDir)
  366. # get filename from ExperimentHandler for convenience
  367. filename = thisExp.dataFileName
  368. frameTolerance = 0.001 # how close to onset before 'same' frame
  369. endExpNow = False # flag for 'escape' or other condition => quit the exp
  370. # get frame duration from frame rate in expInfo
  371. if 'frameRate' in expInfo and expInfo['frameRate'] is not None:
  372. frameDur = 1.0 / round(expInfo['frameRate'])
  373. else:
  374. frameDur = 1.0 / 60.0 # could not measure, so guess
  375. # Start Code - component code to be run after the window creation
  376. # --- Initialize components for Routine "Prep" ---
  377. # Run 'Begin Experiment' code from code
  378. info = StreamInfo(name='Trigger', type='Markers', channel_count=1, channel_format='int32', source_id='Example')
  379. outlet = StreamOutlet(info)
  380. group = expInfo['Situation']
  381. sess = expInfo['session']
  382. if group == "1":
  383. folder = situations["Situation1"]
  384. elif group == "2":
  385. folder = situations["Situation2"]
  386. elif group == "3":
  387. folder = situations["Situation3"]
  388. elif group == "4":
  389. folder = situations["Situation4"]
  390. elif group == "5":
  391. folder = situations["Situation5"]
  392. elif group == "6":
  393. folder = situations["Situation6"]
  394. elif group == "7":
  395. folder = situations["Situation7"]
  396. elif group == "8":
  397. folder = situations["Situation8"]
  398. elif group == "9":
  399. folder = situations["Situation9"]
  400. elif group == "10":
  401. folder = situations["Situation10"]
  402. elif group == "11":
  403. folder = situations["Situation11"]
  404. elif group == "12":
  405. folder = situations["Situation12"]
  406. elif group == "13":
  407. folder = situations["Situation13"]
  408. elif group == "14":
  409. folder = situations["Situation14"]
  410. elif group == "15":
  411. folder = situations["Situation15"]
  412. elif group == "16":
  413. folder = situations["Situation16"]
  414. elif group == "17":
  415. folder = situations["Situation17"]
  416. elif group == "18":
  417. folder = situations["Situation18"]
  418. elif group == "19":
  419. folder = situations["Situation19"]
  420. random.shuffle(ctr_lst)
  421. random.shuffle(str_lst)
  422. # --- Initialize components for Routine "check_lsl" ---
  423. key_resp = keyboard.Keyboard(deviceName='key_resp')
  424. text_4 = visual.TextStim(win=win, name='text_4',
  425. text='Por favor verifique se a luz verde de trigger está presente no programa aurora antes de avançar.\n\nApós verificar o trigger pode explicar ao participante como procederá a sessão. Explique a tarefa de linha de base:\n\n"Por favor sente-se relaxado e como os olhos fechados durante os próximos 3 minutos, eu aviso quando o tempo chegar ao fim."\n\nApós verificar pode começar o protocolo com a barra de espaços.',
  426. font='Arial',
  427. pos=(0, 0), draggable=False, height=0.05, wrapWidth=None, ori=0.0,
  428. color='white', colorSpace='rgb', opacity=None,
  429. languageStyle='LTR',
  430. depth=-1.0);
  431. # --- Initialize components for Routine "baseline" ---
  432. polygon = visual.ShapeStim(
  433. win=win, name='polygon', vertices='cross',
  434. size=(0.5, 0.5),
  435. ori=0.0, pos=(0, 0), draggable=False, anchor='center',
  436. lineWidth=1.0,
  437. colorSpace='rgb', lineColor='white', fillColor='white',
  438. opacity=None, depth=-1.0, interpolate=True)
  439. # --- Initialize components for Routine "present_situation" ---
  440. sound_1 = sound.Sound(
  441. 'A',
  442. secs=-1,
  443. stereo=True,
  444. hamming=True,
  445. speaker='sound_1', name='sound_1'
  446. )
  447. sound_1.setVolume(1.0)
  448. text = visual.TextStim(win=win, name='text',
  449. text='Explicação de contexto a decorrer\n',
  450. font='Arial',
  451. pos=(0, 0), draggable=False, height=0.05, wrapWidth=None, ori=0.0,
  452. color='white', colorSpace='rgb', opacity=None,
  453. languageStyle='LTR',
  454. depth=-2.0);
  455. # --- Initialize components for Routine "it_setter" ---
  456. # --- Initialize components for Routine "stressor" ---
  457. sound_2 = sound.Sound(
  458. 'A',
  459. secs=-1,
  460. stereo=True,
  461. hamming=True,
  462. speaker='sound_2', name='sound_2'
  463. )
  464. sound_2.setVolume(1.0)
  465. text_2 = visual.TextStim(win=win, name='text_2',
  466. text='A apresentar stressor',
  467. font='Arial',
  468. pos=(0, 0), draggable=False, height=0.05, wrapWidth=None, ori=0.0,
  469. color='white', colorSpace='rgb', opacity=None,
  470. languageStyle='LTR',
  471. depth=-2.0);
  472. # --- Initialize components for Routine "it_ctr" ---
  473. # --- Initialize components for Routine "control" ---
  474. sound_3 = sound.Sound(
  475. 'A',
  476. secs=-1,
  477. stereo=True,
  478. hamming=True,
  479. speaker='sound_3', name='sound_3'
  480. )
  481. sound_3.setVolume(1.0)
  482. text_3 = visual.TextStim(win=win, name='text_3',
  483. text='A apresentar controlo',
  484. font='Arial',
  485. pos=(0, 0), draggable=False, height=0.05, wrapWidth=None, ori=0.0,
  486. color='white', colorSpace='rgb', opacity=None,
  487. languageStyle='LTR',
  488. depth=-2.0);
  489. # --- Initialize components for Routine "ender" ---
  490. text_7 = visual.TextStim(win=win, name='text_7',
  491. text='Sessão finalizada\n',
  492. font='Arial',
  493. pos=(0, 0), draggable=False, height=0.05, wrapWidth=None, ori=0.0,
  494. color='white', colorSpace='rgb', opacity=None,
  495. languageStyle='LTR',
  496. depth=-1.0);
  497. # create some handy timers
  498. # global clock to track the time since experiment started
  499. if globalClock is None:
  500. # create a clock if not given one
  501. globalClock = core.Clock()
  502. if isinstance(globalClock, str):
  503. # if given a string, make a clock accoridng to it
  504. if globalClock == 'float':
  505. # get timestamps as a simple value
  506. globalClock = core.Clock(format='float')
  507. elif globalClock == 'iso':
  508. # get timestamps in ISO format
  509. globalClock = core.Clock(format='%Y-%m-%d_%H:%M:%S.%f%z')
  510. else:
  511. # get timestamps in a custom format
  512. globalClock = core.Clock(format=globalClock)
  513. if ioServer is not None:
  514. ioServer.syncClock(globalClock)
  515. logging.setDefaultClock(globalClock)
  516. # routine timer to track time remaining of each (possibly non-slip) routine
  517. routineTimer = core.Clock()
  518. win.flip() # flip window to reset last flip timer
  519. # store the exact time the global clock started
  520. expInfo['expStart'] = data.getDateStr(
  521. format='%Y-%m-%d %Hh%M.%S.%f %z', fractionalSecondDigits=6
  522. )
  523. # --- Prepare to start Routine "Prep" ---
  524. # create an object to store info about Routine Prep
  525. Prep = data.Routine(
  526. name='Prep',
  527. components=[],
  528. )
  529. Prep.status = NOT_STARTED
  530. continueRoutine = True
  531. # update component parameters for each repeat
  532. # Run 'Begin Routine' code from code
  533. outlet.push_sample(x=[0])
  534. # store start times for Prep
  535. Prep.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  536. Prep.tStart = globalClock.getTime(format='float')
  537. Prep.status = STARTED
  538. thisExp.addData('Prep.started', Prep.tStart)
  539. Prep.maxDuration = None
  540. # keep track of which components have finished
  541. PrepComponents = Prep.components
  542. for thisComponent in Prep.components:
  543. thisComponent.tStart = None
  544. thisComponent.tStop = None
  545. thisComponent.tStartRefresh = None
  546. thisComponent.tStopRefresh = None
  547. if hasattr(thisComponent, 'status'):
  548. thisComponent.status = NOT_STARTED
  549. # reset timers
  550. t = 0
  551. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  552. frameN = -1
  553. # --- Run Routine "Prep" ---
  554. Prep.forceEnded = routineForceEnded = not continueRoutine
  555. while continueRoutine:
  556. # get current time
  557. t = routineTimer.getTime()
  558. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  559. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  560. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  561. # update/draw components on each frame
  562. # check for quit (typically the Esc key)
  563. if defaultKeyboard.getKeys(keyList=["escape"]):
  564. thisExp.status = FINISHED
  565. if thisExp.status == FINISHED or endExpNow:
  566. endExperiment(thisExp, win=win)
  567. return
  568. # pause experiment here if requested
  569. if thisExp.status == PAUSED:
  570. pauseExperiment(
  571. thisExp=thisExp,
  572. win=win,
  573. timers=[routineTimer],
  574. playbackComponents=[]
  575. )
  576. # skip the frame we paused on
  577. continue
  578. # check if all components have finished
  579. if not continueRoutine: # a component has requested a forced-end of Routine
  580. Prep.forceEnded = routineForceEnded = True
  581. break
  582. continueRoutine = False # will revert to True if at least one component still running
  583. for thisComponent in Prep.components:
  584. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  585. continueRoutine = True
  586. break # at least one component has not yet finished
  587. # refresh the screen
  588. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  589. win.flip()
  590. # --- Ending Routine "Prep" ---
  591. for thisComponent in Prep.components:
  592. if hasattr(thisComponent, "setAutoDraw"):
  593. thisComponent.setAutoDraw(False)
  594. # store stop times for Prep
  595. Prep.tStop = globalClock.getTime(format='float')
  596. Prep.tStopRefresh = tThisFlipGlobal
  597. thisExp.addData('Prep.stopped', Prep.tStop)
  598. thisExp.nextEntry()
  599. # the Routine "Prep" was not non-slip safe, so reset the non-slip timer
  600. routineTimer.reset()
  601. # --- Prepare to start Routine "check_lsl" ---
  602. # create an object to store info about Routine check_lsl
  603. check_lsl = data.Routine(
  604. name='check_lsl',
  605. components=[key_resp, text_4],
  606. )
  607. check_lsl.status = NOT_STARTED
  608. continueRoutine = True
  609. # update component parameters for each repeat
  610. # create starting attributes for key_resp
  611. key_resp.keys = []
  612. key_resp.rt = []
  613. _key_resp_allKeys = []
  614. # store start times for check_lsl
  615. check_lsl.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  616. check_lsl.tStart = globalClock.getTime(format='float')
  617. check_lsl.status = STARTED
  618. thisExp.addData('check_lsl.started', check_lsl.tStart)
  619. check_lsl.maxDuration = None
  620. # keep track of which components have finished
  621. check_lslComponents = check_lsl.components
  622. for thisComponent in check_lsl.components:
  623. thisComponent.tStart = None
  624. thisComponent.tStop = None
  625. thisComponent.tStartRefresh = None
  626. thisComponent.tStopRefresh = None
  627. if hasattr(thisComponent, 'status'):
  628. thisComponent.status = NOT_STARTED
  629. # reset timers
  630. t = 0
  631. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  632. frameN = -1
  633. # --- Run Routine "check_lsl" ---
  634. check_lsl.forceEnded = routineForceEnded = not continueRoutine
  635. while continueRoutine:
  636. # get current time
  637. t = routineTimer.getTime()
  638. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  639. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  640. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  641. # update/draw components on each frame
  642. # *key_resp* updates
  643. waitOnFlip = False
  644. # if key_resp is starting this frame...
  645. if key_resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  646. # keep track of start time/frame for later
  647. key_resp.frameNStart = frameN # exact frame index
  648. key_resp.tStart = t # local t and not account for scr refresh
  649. key_resp.tStartRefresh = tThisFlipGlobal # on global time
  650. win.timeOnFlip(key_resp, 'tStartRefresh') # time at next scr refresh
  651. # add timestamp to datafile
  652. thisExp.timestampOnFlip(win, 'key_resp.started')
  653. # update status
  654. key_resp.status = STARTED
  655. # keyboard checking is just starting
  656. waitOnFlip = True
  657. win.callOnFlip(key_resp.clock.reset) # t=0 on next screen flip
  658. win.callOnFlip(key_resp.clearEvents, eventType='keyboard') # clear events on next screen flip
  659. if key_resp.status == STARTED and not waitOnFlip:
  660. theseKeys = key_resp.getKeys(keyList=['space'], ignoreKeys=["escape"], waitRelease=False)
  661. _key_resp_allKeys.extend(theseKeys)
  662. if len(_key_resp_allKeys):
  663. key_resp.keys = _key_resp_allKeys[-1].name # just the last key pressed
  664. key_resp.rt = _key_resp_allKeys[-1].rt
  665. key_resp.duration = _key_resp_allKeys[-1].duration
  666. # a response ends the routine
  667. continueRoutine = False
  668. # *text_4* updates
  669. # if text_4 is starting this frame...
  670. if text_4.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  671. # keep track of start time/frame for later
  672. text_4.frameNStart = frameN # exact frame index
  673. text_4.tStart = t # local t and not account for scr refresh
  674. text_4.tStartRefresh = tThisFlipGlobal # on global time
  675. win.timeOnFlip(text_4, 'tStartRefresh') # time at next scr refresh
  676. # add timestamp to datafile
  677. thisExp.timestampOnFlip(win, 'text_4.started')
  678. # update status
  679. text_4.status = STARTED
  680. text_4.setAutoDraw(True)
  681. # if text_4 is active this frame...
  682. if text_4.status == STARTED:
  683. # update params
  684. pass
  685. # check for quit (typically the Esc key)
  686. if defaultKeyboard.getKeys(keyList=["escape"]):
  687. thisExp.status = FINISHED
  688. if thisExp.status == FINISHED or endExpNow:
  689. endExperiment(thisExp, win=win)
  690. return
  691. # pause experiment here if requested
  692. if thisExp.status == PAUSED:
  693. pauseExperiment(
  694. thisExp=thisExp,
  695. win=win,
  696. timers=[routineTimer],
  697. playbackComponents=[]
  698. )
  699. # skip the frame we paused on
  700. continue
  701. # check if all components have finished
  702. if not continueRoutine: # a component has requested a forced-end of Routine
  703. check_lsl.forceEnded = routineForceEnded = True
  704. break
  705. continueRoutine = False # will revert to True if at least one component still running
  706. for thisComponent in check_lsl.components:
  707. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  708. continueRoutine = True
  709. break # at least one component has not yet finished
  710. # refresh the screen
  711. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  712. win.flip()
  713. # --- Ending Routine "check_lsl" ---
  714. for thisComponent in check_lsl.components:
  715. if hasattr(thisComponent, "setAutoDraw"):
  716. thisComponent.setAutoDraw(False)
  717. # store stop times for check_lsl
  718. check_lsl.tStop = globalClock.getTime(format='float')
  719. check_lsl.tStopRefresh = tThisFlipGlobal
  720. thisExp.addData('check_lsl.stopped', check_lsl.tStop)
  721. # check responses
  722. if key_resp.keys in ['', [], None]: # No response was made
  723. key_resp.keys = None
  724. thisExp.addData('key_resp.keys',key_resp.keys)
  725. if key_resp.keys != None: # we had a response
  726. thisExp.addData('key_resp.rt', key_resp.rt)
  727. thisExp.addData('key_resp.duration', key_resp.duration)
  728. thisExp.nextEntry()
  729. # the Routine "check_lsl" was not non-slip safe, so reset the non-slip timer
  730. routineTimer.reset()
  731. # --- Prepare to start Routine "baseline" ---
  732. # create an object to store info about Routine baseline
  733. baseline = data.Routine(
  734. name='baseline',
  735. components=[polygon],
  736. )
  737. baseline.status = NOT_STARTED
  738. continueRoutine = True
  739. # update component parameters for each repeat
  740. # Run 'Begin Routine' code from code_7
  741. outlet.push_sample(x=[1])
  742. start = time.time()
  743. texted = 0
  744. # store start times for baseline
  745. baseline.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  746. baseline.tStart = globalClock.getTime(format='float')
  747. baseline.status = STARTED
  748. thisExp.addData('baseline.started', baseline.tStart)
  749. baseline.maxDuration = None
  750. # keep track of which components have finished
  751. baselineComponents = baseline.components
  752. for thisComponent in baseline.components:
  753. thisComponent.tStart = None
  754. thisComponent.tStop = None
  755. thisComponent.tStartRefresh = None
  756. thisComponent.tStopRefresh = None
  757. if hasattr(thisComponent, 'status'):
  758. thisComponent.status = NOT_STARTED
  759. # reset timers
  760. t = 0
  761. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  762. frameN = -1
  763. # --- Run Routine "baseline" ---
  764. baseline.forceEnded = routineForceEnded = not continueRoutine
  765. while continueRoutine and routineTimer.getTime() < 180.0:
  766. # get current time
  767. t = routineTimer.getTime()
  768. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  769. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  770. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  771. # update/draw components on each frame
  772. # Run 'Each Frame' code from code_7
  773. timer = time.time() - start
  774. texted = f'{timer}'
  775. if timer > 180:
  776. continueRoutine = False
  777. # *polygon* updates
  778. # if polygon is starting this frame...
  779. if polygon.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  780. # keep track of start time/frame for later
  781. polygon.frameNStart = frameN # exact frame index
  782. polygon.tStart = t # local t and not account for scr refresh
  783. polygon.tStartRefresh = tThisFlipGlobal # on global time
  784. win.timeOnFlip(polygon, 'tStartRefresh') # time at next scr refresh
  785. # add timestamp to datafile
  786. thisExp.timestampOnFlip(win, 'polygon.started')
  787. # update status
  788. polygon.status = STARTED
  789. polygon.setAutoDraw(True)
  790. # if polygon is active this frame...
  791. if polygon.status == STARTED:
  792. # update params
  793. pass
  794. # if polygon is stopping this frame...
  795. if polygon.status == STARTED:
  796. # is it time to stop? (based on global clock, using actual start)
  797. if tThisFlipGlobal > polygon.tStartRefresh + 180-frameTolerance:
  798. # keep track of stop time/frame for later
  799. polygon.tStop = t # not accounting for scr refresh
  800. polygon.tStopRefresh = tThisFlipGlobal # on global time
  801. polygon.frameNStop = frameN # exact frame index
  802. # add timestamp to datafile
  803. thisExp.timestampOnFlip(win, 'polygon.stopped')
  804. # update status
  805. polygon.status = FINISHED
  806. polygon.setAutoDraw(False)
  807. # check for quit (typically the Esc key)
  808. if defaultKeyboard.getKeys(keyList=["escape"]):
  809. thisExp.status = FINISHED
  810. if thisExp.status == FINISHED or endExpNow:
  811. endExperiment(thisExp, win=win)
  812. return
  813. # pause experiment here if requested
  814. if thisExp.status == PAUSED:
  815. pauseExperiment(
  816. thisExp=thisExp,
  817. win=win,
  818. timers=[routineTimer],
  819. playbackComponents=[]
  820. )
  821. # skip the frame we paused on
  822. continue
  823. # check if all components have finished
  824. if not continueRoutine: # a component has requested a forced-end of Routine
  825. baseline.forceEnded = routineForceEnded = True
  826. break
  827. continueRoutine = False # will revert to True if at least one component still running
  828. for thisComponent in baseline.components:
  829. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  830. continueRoutine = True
  831. break # at least one component has not yet finished
  832. # refresh the screen
  833. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  834. win.flip()
  835. # --- Ending Routine "baseline" ---
  836. for thisComponent in baseline.components:
  837. if hasattr(thisComponent, "setAutoDraw"):
  838. thisComponent.setAutoDraw(False)
  839. # store stop times for baseline
  840. baseline.tStop = globalClock.getTime(format='float')
  841. baseline.tStopRefresh = tThisFlipGlobal
  842. thisExp.addData('baseline.stopped', baseline.tStop)
  843. # Run 'End Routine' code from code_7
  844. outlet.push_sample(x=[2])
  845. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  846. if baseline.maxDurationReached:
  847. routineTimer.addTime(-baseline.maxDuration)
  848. elif baseline.forceEnded:
  849. routineTimer.reset()
  850. else:
  851. routineTimer.addTime(-180.000000)
  852. thisExp.nextEntry()
  853. # --- Prepare to start Routine "present_situation" ---
  854. # create an object to store info about Routine present_situation
  855. present_situation = data.Routine(
  856. name='present_situation',
  857. components=[sound_1, text],
  858. )
  859. present_situation.status = NOT_STARTED
  860. continueRoutine = True
  861. # update component parameters for each repeat
  862. # Run 'Begin Routine' code from code_2
  863. outlet.push_sample(x=[3])
  864. sound_1.setSound(f'{folder}situation.wav', secs=60, hamming=True)
  865. sound_1.setVolume(1.0, log=False)
  866. sound_1.seek(0)
  867. # store start times for present_situation
  868. present_situation.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  869. present_situation.tStart = globalClock.getTime(format='float')
  870. present_situation.status = STARTED
  871. thisExp.addData('present_situation.started', present_situation.tStart)
  872. present_situation.maxDuration = None
  873. # keep track of which components have finished
  874. present_situationComponents = present_situation.components
  875. for thisComponent in present_situation.components:
  876. thisComponent.tStart = None
  877. thisComponent.tStop = None
  878. thisComponent.tStartRefresh = None
  879. thisComponent.tStopRefresh = None
  880. if hasattr(thisComponent, 'status'):
  881. thisComponent.status = NOT_STARTED
  882. # reset timers
  883. t = 0
  884. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  885. frameN = -1
  886. # --- Run Routine "present_situation" ---
  887. present_situation.forceEnded = routineForceEnded = not continueRoutine
  888. while continueRoutine and routineTimer.getTime() < 60.0:
  889. # get current time
  890. t = routineTimer.getTime()
  891. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  892. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  893. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  894. # update/draw components on each frame
  895. # *sound_1* updates
  896. # if sound_1 is starting this frame...
  897. if sound_1.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  898. # keep track of start time/frame for later
  899. sound_1.frameNStart = frameN # exact frame index
  900. sound_1.tStart = t # local t and not account for scr refresh
  901. sound_1.tStartRefresh = tThisFlipGlobal # on global time
  902. # add timestamp to datafile
  903. thisExp.addData('sound_1.started', tThisFlipGlobal)
  904. # update status
  905. sound_1.status = STARTED
  906. sound_1.play(when=win) # sync with win flip
  907. # if sound_1 is stopping this frame...
  908. if sound_1.status == STARTED:
  909. # is it time to stop? (based on global clock, using actual start)
  910. if tThisFlipGlobal > sound_1.tStartRefresh + 60-frameTolerance or sound_1.isFinished:
  911. # keep track of stop time/frame for later
  912. sound_1.tStop = t # not accounting for scr refresh
  913. sound_1.tStopRefresh = tThisFlipGlobal # on global time
  914. sound_1.frameNStop = frameN # exact frame index
  915. # add timestamp to datafile
  916. thisExp.timestampOnFlip(win, 'sound_1.stopped')
  917. # update status
  918. sound_1.status = FINISHED
  919. sound_1.stop()
  920. # *text* updates
  921. # if text is starting this frame...
  922. if text.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  923. # keep track of start time/frame for later
  924. text.frameNStart = frameN # exact frame index
  925. text.tStart = t # local t and not account for scr refresh
  926. text.tStartRefresh = tThisFlipGlobal # on global time
  927. win.timeOnFlip(text, 'tStartRefresh') # time at next scr refresh
  928. # add timestamp to datafile
  929. thisExp.timestampOnFlip(win, 'text.started')
  930. # update status
  931. text.status = STARTED
  932. text.setAutoDraw(True)
  933. # if text is active this frame...
  934. if text.status == STARTED:
  935. # update params
  936. pass
  937. # if text is stopping this frame...
  938. if text.status == STARTED:
  939. # is it time to stop? (based on global clock, using actual start)
  940. if tThisFlipGlobal > text.tStartRefresh + 60-frameTolerance:
  941. # keep track of stop time/frame for later
  942. text.tStop = t # not accounting for scr refresh
  943. text.tStopRefresh = tThisFlipGlobal # on global time
  944. text.frameNStop = frameN # exact frame index
  945. # add timestamp to datafile
  946. thisExp.timestampOnFlip(win, 'text.stopped')
  947. # update status
  948. text.status = FINISHED
  949. text.setAutoDraw(False)
  950. # check for quit (typically the Esc key)
  951. if defaultKeyboard.getKeys(keyList=["escape"]):
  952. thisExp.status = FINISHED
  953. if thisExp.status == FINISHED or endExpNow:
  954. endExperiment(thisExp, win=win)
  955. return
  956. # pause experiment here if requested
  957. if thisExp.status == PAUSED:
  958. pauseExperiment(
  959. thisExp=thisExp,
  960. win=win,
  961. timers=[routineTimer],
  962. playbackComponents=[sound_1]
  963. )
  964. # skip the frame we paused on
  965. continue
  966. # check if all components have finished
  967. if not continueRoutine: # a component has requested a forced-end of Routine
  968. present_situation.forceEnded = routineForceEnded = True
  969. break
  970. continueRoutine = False # will revert to True if at least one component still running
  971. for thisComponent in present_situation.components:
  972. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  973. continueRoutine = True
  974. break # at least one component has not yet finished
  975. # refresh the screen
  976. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  977. win.flip()
  978. # --- Ending Routine "present_situation" ---
  979. for thisComponent in present_situation.components:
  980. if hasattr(thisComponent, "setAutoDraw"):
  981. thisComponent.setAutoDraw(False)
  982. # store stop times for present_situation
  983. present_situation.tStop = globalClock.getTime(format='float')
  984. present_situation.tStopRefresh = tThisFlipGlobal
  985. thisExp.addData('present_situation.stopped', present_situation.tStop)
  986. # Run 'End Routine' code from code_2
  987. outlet.push_sample(x=[4])
  988. sound_1.pause() # ensure sound has stopped at end of Routine
  989. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  990. if present_situation.maxDurationReached:
  991. routineTimer.addTime(-present_situation.maxDuration)
  992. elif present_situation.forceEnded:
  993. routineTimer.reset()
  994. else:
  995. routineTimer.addTime(-60.000000)
  996. thisExp.nextEntry()
  997. # set up handler to look after randomisation of conditions etc
  998. trials = data.TrialHandler2(
  999. name='trials',
  1000. nReps=5.0,
  1001. method='random',
  1002. extraInfo=expInfo,
  1003. originPath=-1,
  1004. trialList=[None],
  1005. seed=None,
  1006. )
  1007. thisExp.addLoop(trials) # add the loop to the experiment
  1008. thisTrial = trials.trialList[0] # so we can initialise stimuli with some values
  1009. # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
  1010. if thisTrial != None:
  1011. for paramName in thisTrial:
  1012. globals()[paramName] = thisTrial[paramName]
  1013. if thisSession is not None:
  1014. # if running in a Session with a Liaison client, send data up to now
  1015. thisSession.sendExperimentData()
  1016. for thisTrial in trials:
  1017. currentLoop = trials
  1018. thisExp.timestampOnFlip(win, 'thisRow.t', format=globalClock.format)
  1019. if thisSession is not None:
  1020. # if running in a Session with a Liaison client, send data up to now
  1021. thisSession.sendExperimentData()
  1022. # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
  1023. if thisTrial != None:
  1024. for paramName in thisTrial:
  1025. globals()[paramName] = thisTrial[paramName]
  1026. # --- Prepare to start Routine "it_setter" ---
  1027. # create an object to store info about Routine it_setter
  1028. it_setter = data.Routine(
  1029. name='it_setter',
  1030. components=[],
  1031. )
  1032. it_setter.status = NOT_STARTED
  1033. continueRoutine = True
  1034. # update component parameters for each repeat
  1035. # Run 'Begin Routine' code from code_3
  1036. iteration = str_lst.pop(0)
  1037. stressvar = f'stressvar{iteration}'
  1038. # store start times for it_setter
  1039. it_setter.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  1040. it_setter.tStart = globalClock.getTime(format='float')
  1041. it_setter.status = STARTED
  1042. thisExp.addData('it_setter.started', it_setter.tStart)
  1043. it_setter.maxDuration = None
  1044. # keep track of which components have finished
  1045. it_setterComponents = it_setter.components
  1046. for thisComponent in it_setter.components:
  1047. thisComponent.tStart = None
  1048. thisComponent.tStop = None
  1049. thisComponent.tStartRefresh = None
  1050. thisComponent.tStopRefresh = None
  1051. if hasattr(thisComponent, 'status'):
  1052. thisComponent.status = NOT_STARTED
  1053. # reset timers
  1054. t = 0
  1055. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  1056. frameN = -1
  1057. # --- Run Routine "it_setter" ---
  1058. # if trial has changed, end Routine now
  1059. if isinstance(trials, data.TrialHandler2) and thisTrial.thisN != trials.thisTrial.thisN:
  1060. continueRoutine = False
  1061. it_setter.forceEnded = routineForceEnded = not continueRoutine
  1062. while continueRoutine:
  1063. # get current time
  1064. t = routineTimer.getTime()
  1065. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  1066. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  1067. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  1068. # update/draw components on each frame
  1069. # check for quit (typically the Esc key)
  1070. if defaultKeyboard.getKeys(keyList=["escape"]):
  1071. thisExp.status = FINISHED
  1072. if thisExp.status == FINISHED or endExpNow:
  1073. endExperiment(thisExp, win=win)
  1074. return
  1075. # pause experiment here if requested
  1076. if thisExp.status == PAUSED:
  1077. pauseExperiment(
  1078. thisExp=thisExp,
  1079. win=win,
  1080. timers=[routineTimer],
  1081. playbackComponents=[]
  1082. )
  1083. # skip the frame we paused on
  1084. continue
  1085. # check if all components have finished
  1086. if not continueRoutine: # a component has requested a forced-end of Routine
  1087. it_setter.forceEnded = routineForceEnded = True
  1088. break
  1089. continueRoutine = False # will revert to True if at least one component still running
  1090. for thisComponent in it_setter.components:
  1091. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  1092. continueRoutine = True
  1093. break # at least one component has not yet finished
  1094. # refresh the screen
  1095. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  1096. win.flip()
  1097. # --- Ending Routine "it_setter" ---
  1098. for thisComponent in it_setter.components:
  1099. if hasattr(thisComponent, "setAutoDraw"):
  1100. thisComponent.setAutoDraw(False)
  1101. # store stop times for it_setter
  1102. it_setter.tStop = globalClock.getTime(format='float')
  1103. it_setter.tStopRefresh = tThisFlipGlobal
  1104. thisExp.addData('it_setter.stopped', it_setter.tStop)
  1105. # the Routine "it_setter" was not non-slip safe, so reset the non-slip timer
  1106. routineTimer.reset()
  1107. # --- Prepare to start Routine "stressor" ---
  1108. # create an object to store info about Routine stressor
  1109. stressor = data.Routine(
  1110. name='stressor',
  1111. components=[sound_2, text_2],
  1112. )
  1113. stressor.status = NOT_STARTED
  1114. continueRoutine = True
  1115. # update component parameters for each repeat
  1116. # Run 'Begin Routine' code from code_4
  1117. outlet.push_sample(x=[5])
  1118. sound_2.setSound(f'./BIN/Recordings/Session/Session{sess}/{stressvar}.wav', secs=30, hamming=True)
  1119. sound_2.setVolume(1.0, log=False)
  1120. sound_2.seek(0)
  1121. # store start times for stressor
  1122. stressor.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  1123. stressor.tStart = globalClock.getTime(format='float')
  1124. stressor.status = STARTED
  1125. thisExp.addData('stressor.started', stressor.tStart)
  1126. stressor.maxDuration = None
  1127. # keep track of which components have finished
  1128. stressorComponents = stressor.components
  1129. for thisComponent in stressor.components:
  1130. thisComponent.tStart = None
  1131. thisComponent.tStop = None
  1132. thisComponent.tStartRefresh = None
  1133. thisComponent.tStopRefresh = None
  1134. if hasattr(thisComponent, 'status'):
  1135. thisComponent.status = NOT_STARTED
  1136. # reset timers
  1137. t = 0
  1138. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  1139. frameN = -1
  1140. # --- Run Routine "stressor" ---
  1141. # if trial has changed, end Routine now
  1142. if isinstance(trials, data.TrialHandler2) and thisTrial.thisN != trials.thisTrial.thisN:
  1143. continueRoutine = False
  1144. stressor.forceEnded = routineForceEnded = not continueRoutine
  1145. while continueRoutine and routineTimer.getTime() < 30.0:
  1146. # get current time
  1147. t = routineTimer.getTime()
  1148. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  1149. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  1150. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  1151. # update/draw components on each frame
  1152. # *sound_2* updates
  1153. # if sound_2 is starting this frame...
  1154. if sound_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  1155. # keep track of start time/frame for later
  1156. sound_2.frameNStart = frameN # exact frame index
  1157. sound_2.tStart = t # local t and not account for scr refresh
  1158. sound_2.tStartRefresh = tThisFlipGlobal # on global time
  1159. # add timestamp to datafile
  1160. thisExp.addData('sound_2.started', tThisFlipGlobal)
  1161. # update status
  1162. sound_2.status = STARTED
  1163. sound_2.play(when=win) # sync with win flip
  1164. # if sound_2 is stopping this frame...
  1165. if sound_2.status == STARTED:
  1166. # is it time to stop? (based on global clock, using actual start)
  1167. if tThisFlipGlobal > sound_2.tStartRefresh + 30-frameTolerance or sound_2.isFinished:
  1168. # keep track of stop time/frame for later
  1169. sound_2.tStop = t # not accounting for scr refresh
  1170. sound_2.tStopRefresh = tThisFlipGlobal # on global time
  1171. sound_2.frameNStop = frameN # exact frame index
  1172. # add timestamp to datafile
  1173. thisExp.timestampOnFlip(win, 'sound_2.stopped')
  1174. # update status
  1175. sound_2.status = FINISHED
  1176. sound_2.stop()
  1177. # *text_2* updates
  1178. # if text_2 is starting this frame...
  1179. if text_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  1180. # keep track of start time/frame for later
  1181. text_2.frameNStart = frameN # exact frame index
  1182. text_2.tStart = t # local t and not account for scr refresh
  1183. text_2.tStartRefresh = tThisFlipGlobal # on global time
  1184. win.timeOnFlip(text_2, 'tStartRefresh') # time at next scr refresh
  1185. # add timestamp to datafile
  1186. thisExp.timestampOnFlip(win, 'text_2.started')
  1187. # update status
  1188. text_2.status = STARTED
  1189. text_2.setAutoDraw(True)
  1190. # if text_2 is active this frame...
  1191. if text_2.status == STARTED:
  1192. # update params
  1193. pass
  1194. # if text_2 is stopping this frame...
  1195. if text_2.status == STARTED:
  1196. # is it time to stop? (based on global clock, using actual start)
  1197. if tThisFlipGlobal > text_2.tStartRefresh + 30-frameTolerance:
  1198. # keep track of stop time/frame for later
  1199. text_2.tStop = t # not accounting for scr refresh
  1200. text_2.tStopRefresh = tThisFlipGlobal # on global time
  1201. text_2.frameNStop = frameN # exact frame index
  1202. # add timestamp to datafile
  1203. thisExp.timestampOnFlip(win, 'text_2.stopped')
  1204. # update status
  1205. text_2.status = FINISHED
  1206. text_2.setAutoDraw(False)
  1207. # check for quit (typically the Esc key)
  1208. if defaultKeyboard.getKeys(keyList=["escape"]):
  1209. thisExp.status = FINISHED
  1210. if thisExp.status == FINISHED or endExpNow:
  1211. endExperiment(thisExp, win=win)
  1212. return
  1213. # pause experiment here if requested
  1214. if thisExp.status == PAUSED:
  1215. pauseExperiment(
  1216. thisExp=thisExp,
  1217. win=win,
  1218. timers=[routineTimer],
  1219. playbackComponents=[sound_2]
  1220. )
  1221. # skip the frame we paused on
  1222. continue
  1223. # check if all components have finished
  1224. if not continueRoutine: # a component has requested a forced-end of Routine
  1225. stressor.forceEnded = routineForceEnded = True
  1226. break
  1227. continueRoutine = False # will revert to True if at least one component still running
  1228. for thisComponent in stressor.components:
  1229. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  1230. continueRoutine = True
  1231. break # at least one component has not yet finished
  1232. # refresh the screen
  1233. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  1234. win.flip()
  1235. # --- Ending Routine "stressor" ---
  1236. for thisComponent in stressor.components:
  1237. if hasattr(thisComponent, "setAutoDraw"):
  1238. thisComponent.setAutoDraw(False)
  1239. # store stop times for stressor
  1240. stressor.tStop = globalClock.getTime(format='float')
  1241. stressor.tStopRefresh = tThisFlipGlobal
  1242. thisExp.addData('stressor.stopped', stressor.tStop)
  1243. # Run 'End Routine' code from code_4
  1244. outlet.push_sample(x=[6])
  1245. sound_2.pause() # ensure sound has stopped at end of Routine
  1246. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  1247. if stressor.maxDurationReached:
  1248. routineTimer.addTime(-stressor.maxDuration)
  1249. elif stressor.forceEnded:
  1250. routineTimer.reset()
  1251. else:
  1252. routineTimer.addTime(-30.000000)
  1253. # set up handler to look after randomisation of conditions etc
  1254. trials_2 = data.TrialHandler2(
  1255. name='trials_2',
  1256. nReps=5.0,
  1257. method='random',
  1258. extraInfo=expInfo,
  1259. originPath=-1,
  1260. trialList=[None],
  1261. seed=None,
  1262. )
  1263. thisExp.addLoop(trials_2) # add the loop to the experiment
  1264. thisTrial_2 = trials_2.trialList[0] # so we can initialise stimuli with some values
  1265. # abbreviate parameter names if possible (e.g. rgb = thisTrial_2.rgb)
  1266. if thisTrial_2 != None:
  1267. for paramName in thisTrial_2:
  1268. globals()[paramName] = thisTrial_2[paramName]
  1269. if thisSession is not None:
  1270. # if running in a Session with a Liaison client, send data up to now
  1271. thisSession.sendExperimentData()
  1272. for thisTrial_2 in trials_2:
  1273. currentLoop = trials_2
  1274. thisExp.timestampOnFlip(win, 'thisRow.t', format=globalClock.format)
  1275. if thisSession is not None:
  1276. # if running in a Session with a Liaison client, send data up to now
  1277. thisSession.sendExperimentData()
  1278. # abbreviate parameter names if possible (e.g. rgb = thisTrial_2.rgb)
  1279. if thisTrial_2 != None:
  1280. for paramName in thisTrial_2:
  1281. globals()[paramName] = thisTrial_2[paramName]
  1282. # --- Prepare to start Routine "it_ctr" ---
  1283. # create an object to store info about Routine it_ctr
  1284. it_ctr = data.Routine(
  1285. name='it_ctr',
  1286. components=[],
  1287. )
  1288. it_ctr.status = NOT_STARTED
  1289. continueRoutine = True
  1290. # update component parameters for each repeat
  1291. # Run 'Begin Routine' code from code_6
  1292. iteration_ctr = ctr_lst.pop(0)
  1293. print(iteration_ctr)
  1294. controlvar = f'controlvar{iteration_ctr}'
  1295. # store start times for it_ctr
  1296. it_ctr.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  1297. it_ctr.tStart = globalClock.getTime(format='float')
  1298. it_ctr.status = STARTED
  1299. thisExp.addData('it_ctr.started', it_ctr.tStart)
  1300. it_ctr.maxDuration = None
  1301. # keep track of which components have finished
  1302. it_ctrComponents = it_ctr.components
  1303. for thisComponent in it_ctr.components:
  1304. thisComponent.tStart = None
  1305. thisComponent.tStop = None
  1306. thisComponent.tStartRefresh = None
  1307. thisComponent.tStopRefresh = None
  1308. if hasattr(thisComponent, 'status'):
  1309. thisComponent.status = NOT_STARTED
  1310. # reset timers
  1311. t = 0
  1312. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  1313. frameN = -1
  1314. # --- Run Routine "it_ctr" ---
  1315. # if trial has changed, end Routine now
  1316. if isinstance(trials_2, data.TrialHandler2) and thisTrial_2.thisN != trials_2.thisTrial.thisN:
  1317. continueRoutine = False
  1318. it_ctr.forceEnded = routineForceEnded = not continueRoutine
  1319. while continueRoutine:
  1320. # get current time
  1321. t = routineTimer.getTime()
  1322. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  1323. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  1324. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  1325. # update/draw components on each frame
  1326. # check for quit (typically the Esc key)
  1327. if defaultKeyboard.getKeys(keyList=["escape"]):
  1328. thisExp.status = FINISHED
  1329. if thisExp.status == FINISHED or endExpNow:
  1330. endExperiment(thisExp, win=win)
  1331. return
  1332. # pause experiment here if requested
  1333. if thisExp.status == PAUSED:
  1334. pauseExperiment(
  1335. thisExp=thisExp,
  1336. win=win,
  1337. timers=[routineTimer],
  1338. playbackComponents=[]
  1339. )
  1340. # skip the frame we paused on
  1341. continue
  1342. # check if all components have finished
  1343. if not continueRoutine: # a component has requested a forced-end of Routine
  1344. it_ctr.forceEnded = routineForceEnded = True
  1345. break
  1346. continueRoutine = False # will revert to True if at least one component still running
  1347. for thisComponent in it_ctr.components:
  1348. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  1349. continueRoutine = True
  1350. break # at least one component has not yet finished
  1351. # refresh the screen
  1352. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  1353. win.flip()
  1354. # --- Ending Routine "it_ctr" ---
  1355. for thisComponent in it_ctr.components:
  1356. if hasattr(thisComponent, "setAutoDraw"):
  1357. thisComponent.setAutoDraw(False)
  1358. # store stop times for it_ctr
  1359. it_ctr.tStop = globalClock.getTime(format='float')
  1360. it_ctr.tStopRefresh = tThisFlipGlobal
  1361. thisExp.addData('it_ctr.stopped', it_ctr.tStop)
  1362. # the Routine "it_ctr" was not non-slip safe, so reset the non-slip timer
  1363. routineTimer.reset()
  1364. # --- Prepare to start Routine "control" ---
  1365. # create an object to store info about Routine control
  1366. control = data.Routine(
  1367. name='control',
  1368. components=[sound_3, text_3],
  1369. )
  1370. control.status = NOT_STARTED
  1371. continueRoutine = True
  1372. # update component parameters for each repeat
  1373. # Run 'Begin Routine' code from code_5
  1374. outlet.push_sample(x=[7])
  1375. sound_3.setSound(f'./BIN/Recordings/Session/Session{sess}/{controlvar}.wav', secs=30, hamming=True)
  1376. sound_3.setVolume(1.0, log=False)
  1377. sound_3.seek(0)
  1378. # store start times for control
  1379. control.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  1380. control.tStart = globalClock.getTime(format='float')
  1381. control.status = STARTED
  1382. thisExp.addData('control.started', control.tStart)
  1383. control.maxDuration = None
  1384. # keep track of which components have finished
  1385. controlComponents = control.components
  1386. for thisComponent in control.components:
  1387. thisComponent.tStart = None
  1388. thisComponent.tStop = None
  1389. thisComponent.tStartRefresh = None
  1390. thisComponent.tStopRefresh = None
  1391. if hasattr(thisComponent, 'status'):
  1392. thisComponent.status = NOT_STARTED
  1393. # reset timers
  1394. t = 0
  1395. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  1396. frameN = -1
  1397. # --- Run Routine "control" ---
  1398. # if trial has changed, end Routine now
  1399. if isinstance(trials_2, data.TrialHandler2) and thisTrial_2.thisN != trials_2.thisTrial.thisN:
  1400. continueRoutine = False
  1401. control.forceEnded = routineForceEnded = not continueRoutine
  1402. while continueRoutine and routineTimer.getTime() < 30.0:
  1403. # get current time
  1404. t = routineTimer.getTime()
  1405. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  1406. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  1407. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  1408. # update/draw components on each frame
  1409. # *sound_3* updates
  1410. # if sound_3 is starting this frame...
  1411. if sound_3.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  1412. # keep track of start time/frame for later
  1413. sound_3.frameNStart = frameN # exact frame index
  1414. sound_3.tStart = t # local t and not account for scr refresh
  1415. sound_3.tStartRefresh = tThisFlipGlobal # on global time
  1416. # add timestamp to datafile
  1417. thisExp.addData('sound_3.started', tThisFlipGlobal)
  1418. # update status
  1419. sound_3.status = STARTED
  1420. sound_3.play(when=win) # sync with win flip
  1421. # if sound_3 is stopping this frame...
  1422. if sound_3.status == STARTED:
  1423. # is it time to stop? (based on global clock, using actual start)
  1424. if tThisFlipGlobal > sound_3.tStartRefresh + 30-frameTolerance or sound_3.isFinished:
  1425. # keep track of stop time/frame for later
  1426. sound_3.tStop = t # not accounting for scr refresh
  1427. sound_3.tStopRefresh = tThisFlipGlobal # on global time
  1428. sound_3.frameNStop = frameN # exact frame index
  1429. # add timestamp to datafile
  1430. thisExp.timestampOnFlip(win, 'sound_3.stopped')
  1431. # update status
  1432. sound_3.status = FINISHED
  1433. sound_3.stop()
  1434. # *text_3* updates
  1435. # if text_3 is starting this frame...
  1436. if text_3.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  1437. # keep track of start time/frame for later
  1438. text_3.frameNStart = frameN # exact frame index
  1439. text_3.tStart = t # local t and not account for scr refresh
  1440. text_3.tStartRefresh = tThisFlipGlobal # on global time
  1441. win.timeOnFlip(text_3, 'tStartRefresh') # time at next scr refresh
  1442. # add timestamp to datafile
  1443. thisExp.timestampOnFlip(win, 'text_3.started')
  1444. # update status
  1445. text_3.status = STARTED
  1446. text_3.setAutoDraw(True)
  1447. # if text_3 is active this frame...
  1448. if text_3.status == STARTED:
  1449. # update params
  1450. pass
  1451. # if text_3 is stopping this frame...
  1452. if text_3.status == STARTED:
  1453. # is it time to stop? (based on global clock, using actual start)
  1454. if tThisFlipGlobal > text_3.tStartRefresh + 30-frameTolerance:
  1455. # keep track of stop time/frame for later
  1456. text_3.tStop = t # not accounting for scr refresh
  1457. text_3.tStopRefresh = tThisFlipGlobal # on global time
  1458. text_3.frameNStop = frameN # exact frame index
  1459. # add timestamp to datafile
  1460. thisExp.timestampOnFlip(win, 'text_3.stopped')
  1461. # update status
  1462. text_3.status = FINISHED
  1463. text_3.setAutoDraw(False)
  1464. # check for quit (typically the Esc key)
  1465. if defaultKeyboard.getKeys(keyList=["escape"]):
  1466. thisExp.status = FINISHED
  1467. if thisExp.status == FINISHED or endExpNow:
  1468. endExperiment(thisExp, win=win)
  1469. return
  1470. # pause experiment here if requested
  1471. if thisExp.status == PAUSED:
  1472. pauseExperiment(
  1473. thisExp=thisExp,
  1474. win=win,
  1475. timers=[routineTimer],
  1476. playbackComponents=[sound_3]
  1477. )
  1478. # skip the frame we paused on
  1479. continue
  1480. # check if all components have finished
  1481. if not continueRoutine: # a component has requested a forced-end of Routine
  1482. control.forceEnded = routineForceEnded = True
  1483. break
  1484. continueRoutine = False # will revert to True if at least one component still running
  1485. for thisComponent in control.components:
  1486. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  1487. continueRoutine = True
  1488. break # at least one component has not yet finished
  1489. # refresh the screen
  1490. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  1491. win.flip()
  1492. # --- Ending Routine "control" ---
  1493. for thisComponent in control.components:
  1494. if hasattr(thisComponent, "setAutoDraw"):
  1495. thisComponent.setAutoDraw(False)
  1496. # store stop times for control
  1497. control.tStop = globalClock.getTime(format='float')
  1498. control.tStopRefresh = tThisFlipGlobal
  1499. thisExp.addData('control.stopped', control.tStop)
  1500. # Run 'End Routine' code from code_5
  1501. outlet.push_sample(x=[8])
  1502. sound_3.pause() # ensure sound has stopped at end of Routine
  1503. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  1504. if control.maxDurationReached:
  1505. routineTimer.addTime(-control.maxDuration)
  1506. elif control.forceEnded:
  1507. routineTimer.reset()
  1508. else:
  1509. routineTimer.addTime(-30.000000)
  1510. thisExp.nextEntry()
  1511. # completed 5.0 repeats of 'trials_2'
  1512. if thisSession is not None:
  1513. # if running in a Session with a Liaison client, send data up to now
  1514. thisSession.sendExperimentData()
  1515. thisExp.nextEntry()
  1516. # completed 5.0 repeats of 'trials'
  1517. if thisSession is not None:
  1518. # if running in a Session with a Liaison client, send data up to now
  1519. thisSession.sendExperimentData()
  1520. # --- Prepare to start Routine "ender" ---
  1521. # create an object to store info about Routine ender
  1522. ender = data.Routine(
  1523. name='ender',
  1524. components=[text_7],
  1525. )
  1526. ender.status = NOT_STARTED
  1527. continueRoutine = True
  1528. # update component parameters for each repeat
  1529. # store start times for ender
  1530. ender.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
  1531. ender.tStart = globalClock.getTime(format='float')
  1532. ender.status = STARTED
  1533. thisExp.addData('ender.started', ender.tStart)
  1534. ender.maxDuration = None
  1535. # keep track of which components have finished
  1536. enderComponents = ender.components
  1537. for thisComponent in ender.components:
  1538. thisComponent.tStart = None
  1539. thisComponent.tStop = None
  1540. thisComponent.tStartRefresh = None
  1541. thisComponent.tStopRefresh = None
  1542. if hasattr(thisComponent, 'status'):
  1543. thisComponent.status = NOT_STARTED
  1544. # reset timers
  1545. t = 0
  1546. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  1547. frameN = -1
  1548. # --- Run Routine "ender" ---
  1549. ender.forceEnded = routineForceEnded = not continueRoutine
  1550. while continueRoutine and routineTimer.getTime() < 5.0:
  1551. # get current time
  1552. t = routineTimer.getTime()
  1553. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  1554. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  1555. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  1556. # update/draw components on each frame
  1557. # *text_7* updates
  1558. # if text_7 is starting this frame...
  1559. if text_7.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  1560. # keep track of start time/frame for later
  1561. text_7.frameNStart = frameN # exact frame index
  1562. text_7.tStart = t # local t and not account for scr refresh
  1563. text_7.tStartRefresh = tThisFlipGlobal # on global time
  1564. win.timeOnFlip(text_7, 'tStartRefresh') # time at next scr refresh
  1565. # add timestamp to datafile
  1566. thisExp.timestampOnFlip(win, 'text_7.started')
  1567. # update status
  1568. text_7.status = STARTED
  1569. text_7.setAutoDraw(True)
  1570. # if text_7 is active this frame...
  1571. if text_7.status == STARTED:
  1572. # update params
  1573. pass
  1574. # if text_7 is stopping this frame...
  1575. if text_7.status == STARTED:
  1576. # is it time to stop? (based on global clock, using actual start)
  1577. if tThisFlipGlobal > text_7.tStartRefresh + 5-frameTolerance:
  1578. # keep track of stop time/frame for later
  1579. text_7.tStop = t # not accounting for scr refresh
  1580. text_7.tStopRefresh = tThisFlipGlobal # on global time
  1581. text_7.frameNStop = frameN # exact frame index
  1582. # add timestamp to datafile
  1583. thisExp.timestampOnFlip(win, 'text_7.stopped')
  1584. # update status
  1585. text_7.status = FINISHED
  1586. text_7.setAutoDraw(False)
  1587. # check for quit (typically the Esc key)
  1588. if defaultKeyboard.getKeys(keyList=["escape"]):
  1589. thisExp.status = FINISHED
  1590. if thisExp.status == FINISHED or endExpNow:
  1591. endExperiment(thisExp, win=win)
  1592. return
  1593. # pause experiment here if requested
  1594. if thisExp.status == PAUSED:
  1595. pauseExperiment(
  1596. thisExp=thisExp,
  1597. win=win,
  1598. timers=[routineTimer],
  1599. playbackComponents=[]
  1600. )
  1601. # skip the frame we paused on
  1602. continue
  1603. # check if all components have finished
  1604. if not continueRoutine: # a component has requested a forced-end of Routine
  1605. ender.forceEnded = routineForceEnded = True
  1606. break
  1607. continueRoutine = False # will revert to True if at least one component still running
  1608. for thisComponent in ender.components:
  1609. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  1610. continueRoutine = True
  1611. break # at least one component has not yet finished
  1612. # refresh the screen
  1613. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  1614. win.flip()
  1615. # --- Ending Routine "ender" ---
  1616. for thisComponent in ender.components:
  1617. if hasattr(thisComponent, "setAutoDraw"):
  1618. thisComponent.setAutoDraw(False)
  1619. # store stop times for ender
  1620. ender.tStop = globalClock.getTime(format='float')
  1621. ender.tStopRefresh = tThisFlipGlobal
  1622. thisExp.addData('ender.stopped', ender.tStop)
  1623. # Run 'End Routine' code from code_8
  1624. outlet.push_sample(x=[99])
  1625. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  1626. if ender.maxDurationReached:
  1627. routineTimer.addTime(-ender.maxDuration)
  1628. elif ender.forceEnded:
  1629. routineTimer.reset()
  1630. else:
  1631. routineTimer.addTime(-5.000000)
  1632. thisExp.nextEntry()
  1633. # mark experiment as finished
  1634. endExperiment(thisExp, win=win)
  1635. def saveData(thisExp):
  1636. """
  1637. Save data from this experiment
  1638. Parameters
  1639. ==========
  1640. thisExp : psychopy.data.ExperimentHandler
  1641. Handler object for this experiment, contains the data to save and information about
  1642. where to save it to.
  1643. """
  1644. filename = thisExp.dataFileName
  1645. # these shouldn't be strictly necessary (should auto-save)
  1646. thisExp.saveAsWideText(filename + '.csv', delim='auto')
  1647. thisExp.saveAsPickle(filename)
  1648. def endExperiment(thisExp, win=None):
  1649. """
  1650. End this experiment, performing final shut down operations.
  1651. This function does NOT close the window or end the Python process - use `quit` for this.
  1652. Parameters
  1653. ==========
  1654. thisExp : psychopy.data.ExperimentHandler
  1655. Handler object for this experiment, contains the data to save and information about
  1656. where to save it to.
  1657. win : psychopy.visual.Window
  1658. Window for this experiment.
  1659. """
  1660. if win is not None:
  1661. # remove autodraw from all current components
  1662. win.clearAutoDraw()
  1663. # Flip one final time so any remaining win.callOnFlip()
  1664. # and win.timeOnFlip() tasks get executed
  1665. win.flip()
  1666. # return console logger level to WARNING
  1667. logging.console.setLevel(logging.WARNING)
  1668. # mark experiment handler as finished
  1669. thisExp.status = FINISHED
  1670. logging.flush()
  1671. def quit(thisExp, win=None, thisSession=None):
  1672. """
  1673. Fully quit, closing the window and ending the Python process.
  1674. Parameters
  1675. ==========
  1676. win : psychopy.visual.Window
  1677. Window to close.
  1678. thisSession : psychopy.session.Session or None
  1679. Handle of the Session object this experiment is being run from, if any.
  1680. """
  1681. thisExp.abort() # or data files will save again on exit
  1682. # make sure everything is closed down
  1683. if win is not None:
  1684. # Flip one final time so any remaining win.callOnFlip()
  1685. # and win.timeOnFlip() tasks get executed before quitting
  1686. win.flip()
  1687. win.close()
  1688. logging.flush()
  1689. if thisSession is not None:
  1690. thisSession.stop()
  1691. # terminate Python process
  1692. core.quit()
  1693. # if running this experiment as a script...
  1694. if __name__ == '__main__':
  1695. # call all functions in order
  1696. expInfo = showExpInfoDlg(expInfo=expInfo)
  1697. thisExp = setupData(expInfo=expInfo)
  1698. logFile = setupLogging(filename=thisExp.dataFileName)
  1699. win = setupWindow(expInfo=expInfo)
  1700. setupDevices(expInfo=expInfo, thisExp=thisExp, win=win)
  1701. run(
  1702. expInfo=expInfo,
  1703. thisExp=thisExp,
  1704. win=win,
  1705. globalClock='float'
  1706. )
  1707. saveData(thisExp=thisExp)
  1708. quit(thisExp=thisExp, win=win)

Model of training_lastrun.py at commit 0bf72a3, no license · at the source

Overview

Authors: Nery Borges1, Pedro Rodrigues Ribeiro2,3,4, Sofia Serra1, Lurdes Veríssimo3,4, Pedro Dias4,5, Nádia Moura6, Inês Silva4, Isaac Raimundo7, Patrícia Oliveira-Silva2,3,4
  1. University of Aveiro, Institute of Ethnomusicology – Centre for Studies in Music and Dance (INET-md), Department of Communication and Arts, Aveiro, Portugal
  2. Universidade Católica Portuguesa, Human Neurobehavioral Laboratory (HNL), Porto, Portugal
  3. Universidade Católica Portuguesa, Faculty of Education and Psychology (FEP), Porto, Portugal
  4. Universidade Católica Portuguesa, Research Centre for Human Development (CEDH), Porto, Portugal
  5. University of the Azores, Department of Psychology, Ponta Delgada, Portugal
  6. University of Coimbra, CEIS20 – Centre for Interdisciplinary Studies, Faculty of Arts and Humanities, Coimbra, Portugal
  7. NOVA University of Lisbon, INET-md, Lisbon, Portugal
Journal: Frontiers in psychology, volume 17, article 1746761
Dates: received 15 November 2025; accepted 10 April 2026; published online 29 April 2026
Type: Methods article · Language: English
License: CC BY
Identifiers: DOI 10.3389/fpsyg.2026.1746761 · PMID 42137087 · PMCID PMC13170606 · OpenAlex W7159650817
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: fNIRS (modality), human (organism), other condition (population), developmental (subfield)
Methods: Spectral & time-frequency, Connectivity, Preprocessing, fMRI & imaging
Keywords: adolescents, gradual exposure, music performance anxiety, neurofeedback-fNIRS, neurophysiological self-regulation
Topic: Diverse Music Education Insights (Music, Arts and Humanities), according to OpenAlex
Citations: cited by 1 paper (Europe PMC); 115 references in the paper

Abstract

Introduction: Music Performance Anxiety (MPA) is a prevalent phenomenon among young musicians, affecting both well-being and artistic performance. Despite its early onset and impact, effective interventions supporting the development of self-regulation of MPA in adolescents remain limited, particularly in relation to neurofeedback-based approaches. In response, this study investigates the feasibility of a Neurofeedback–Functional Near-Infrared Spectroscopy (NFDK-fNIRS) training protocol designed to support this process within a proof-of-concept research framework.

Methods: The protocol alternated MPA induction and regulation within audio-guided sessions conducted in school settings to ensure ecological validity and to integrate top-down control with gradual exposure to performance contexts. The conceptual development and operationalization of the protocol resulted in a theoretical–methodological framework combining gradual exposure, guided imagery, and neurophysiological self-regulation training. This protocol was implemented through standardized auditory scripts and systematic procedures to ensure replicability and experimental coherence. The proof-of-concept implementation was conducted with three female adolescent participants (aged 12–13) across four individual sessions designed to progressively develop physiological self-regulation in response to MPA.

Results: The procedure demonstrated technical feasibility, hemodynamic signal stability, and participants’ gradual adaptation to the training. fNIRS data revealed increased modulation of the dorsolateral prefrontal cortex, consistent with top-down self-regulatory learning mechanisms. Researchers’ reflective journals emphasized practical aspects such as equipment calibration, session duration, and participant engagement.

Discussion: Altogether, the findings indicate that NFDK-fNIRS represents a technically feasible and ecologically applicable approach for training self-regulation of MPA in adolescents, providing a solid foundation for future studies involving larger samples and controlled validation of the protocol.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

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

pedrorribeiro/MUSA-Neurofeedback-training

License: none: the authors keep all their rights
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 0bf72a3c72014b24d45bba7320965e8a25242660, 13 November 2025
Languages: Python (1)
Size: 520 files, 1 script
Software Heritage: not archived
Found in: the text, “System integration”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (1 file), PsychoPy (1 file)
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
1 file

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;
  • 1 script, 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.

Data availability statement

The raw data supporting the conclusions of this article will be made available by the authors, for research purposes, upon request.

Reproduced under the paper's license (CC BY), from the paper cited above.

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, 30 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 9 authors, 5 keywords, 106 references.

Cite

This paper

Borges, N., Ribeiro, P. R., Serra, S., Veríssimo, L., Dias, P., Moura, N., Silva, I., Raimundo, I., & Oliveira-Silva, P. (2026). &lt;i&gt;From concept to proof:&lt;/i&gt; developing a neurofeedback-fNIRS protocol to train self-regulation for music performance anxiety in adolescent musicians. Frontiers in psychology, 17, 1746761. https://doi.org/10.3389/fpsyg.2026.1746761

BibTeX

@article{borges2026lt,
author = {Borges, Nery and Ribeiro, Pedro Rodrigues and Serra, Sofia and Veríssimo, Lurdes and Dias, Pedro and Moura, Nádia and Silva, Inês and Raimundo, Isaac and Oliveira-Silva, Patrícia},
title = {{\&lt;i\&gt;From concept to proof:\&lt;/i\&gt; developing a neurofeedback-fNIRS protocol to train self-regulation for music performance anxiety in adolescent musicians}},
journal = {Frontiers in psychology},
year = {2026},
month = apr,
volume = {17},
pages = {1746761},
publisher = {Frontiers Media SA},
issn = {1664-1078},
doi = {10.3389/fpsyg.2026.1746761},
url = {https://doi.org/10.3389/fpsyg.2026.1746761},
pmid = {42137087},
pmcid = {PMC13170606}
}

RIS

TY - JOUR
AU - Borges, Nery
AU - Ribeiro, Pedro Rodrigues
AU - Serra, Sofia
AU - Veríssimo, Lurdes
AU - Dias, Pedro
AU - Moura, Nádia
AU - Silva, Inês
AU - Raimundo, Isaac
AU - Oliveira-Silva, Patrícia
TI - &lt;i&gt;From concept to proof:&lt;/i&gt; developing a neurofeedback-fNIRS protocol to train self-regulation for music performance anxiety in adolescent musicians
T2 - Frontiers in psychology
J2 - Front Psychol
PY - 2026
DA - 2026/04/29
VL - 17
SP - 1746761
SN - 1664-1078
PB - Frontiers Media SA
DO - 10.3389/fpsyg.2026.1746761
UR - https://doi.org/10.3389/fpsyg.2026.1746761
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fpsyg.2026.1746761",
"type": "article-journal",
"title": "&lt;i&gt;From concept to proof:&lt;/i&gt; developing a neurofeedback-fNIRS protocol to train self-regulation for music performance anxiety in adolescent musicians",
"container-title": "Frontiers in psychology",
"author": [
{
"family": "Borges",
"given": "Nery"
},
{
"family": "Ribeiro",
"given": "Pedro Rodrigues"
},
{
"family": "Serra",
"given": "Sofia"
},
{
"family": "Veríssimo",
"given": "Lurdes"
},
{
"family": "Dias",
"given": "Pedro"
},
{
"family": "Moura",
"given": "Nádia"
},
{
"family": "Silva",
"given": "Inês"
},
{
"family": "Raimundo",
"given": "Isaac"
},
{
"family": "Oliveira-Silva",
"given": "Patrícia"
}
],
"container-title-short": "Front Psychol",
"volume": "17",
"page": "1746761",
"DOI": "10.3389/fpsyg.2026.1746761",
"PMID": "42137087",
"PMCID": "PMC13170606",
"ISSN": "1664-1078",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fpsyg.2026.1746761",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
29
]
]
}
}

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.1117/1.nph.13.3.035009
Single-subject detection of speech network activation using functional near-infrared spectroscopy.
Journal: Neurophotonics
In common: fNIRS, 3 references
[2] doi:10.1371/journal.pbio.3003666 [code]
Emotion regulation success involves systematic gradient-based reconfigurations of large-scale activation patterns in the human brain.
Journal: PLoS biology
In common: NumPy, 3 references
[3] doi:10.1038/s41598-026-49157-z
Supportive neural mechanisms underlying successful emotion regulation for reappraisal success.
Journal: Scientific reports
In common: 3 references
[4] doi:10.3389/fnhum.2026.1806951 [code]
The theta paradox-delayed reduction of frontal midline theta following downregulation neurofeedback training.
Journal: Frontiers in human neuroscience
In common: 3 references
[5] doi:10.1016/j.dcn.2026.101737 [code]
Being praised and criticized in adolescents and adults: Age-related changes in neural responses to social evaluations.
Journal: Developmental cognitive neuroscience
In common: NumPy, developmental, 2 references
[6] doi:10.1007/s00221-026-07354-2 [code]
Transcutaneous auricular vagus nerve stimulation during a 3-back task: a high-density functional near-infrared spectroscopy study.
Journal: Experimental brain research
In common: fNIRS, 2 references
[7] doi:10.1002/brb3.71581 [code]
Blunted Reward Responsiveness During Social Feedback: Associations with Peer Victimization and Anhedonia in Socially Anxious Adolescents.
Journal: Brain and behavior
In common: PsychoPy, NumPy, developmental, other condition
[8] doi:10.1017/s0033291726104309 [code]
A visual cortex origin of trauma memory intrusions: integrated evidence from TMS and fMRI.
Journal: Psychological medicine
In common: NumPy, other condition, 2 references
[9] doi:10.3389/fpsyt.2026.1757213 [code]
A novel music-based real-time fMRI neurofeedback interface modulates interhemispheric connectivity and enhances mood.
Journal: Frontiers in psychiatry
In common: NumPy, 2 references
[10] doi:10.1038/s41467-026-74331-2 [code]
Trial-by-trial fMRI-neurofeedback dissociates fusiform and occipital contributions to face detection and recognition.
Journal: Nature communications
In common: NumPy, 2 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.