train_1.py 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This experiment was created using PsychoPy3 Experiment Builder (v2023.2.3),
  5. on 十一月 08, 2023, at 14:34
  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
  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 exp_prepare_code
  31. import sqlite3
  32. from time import sleep
  33. import streamlit as st
  34. from db.models import train
  35. from core.sig_chain.sig_receive import Receiver
  36. from core.sig_chain.device.connector_interface import Device
  37. from settings.config import settings
  38. # get train record
  39. con = sqlite3.connect("./sql_app.db")
  40. cur = con.cursor()
  41. sql_param = "SELECT * FROM train ORDER BY start_time DESC"
  42. res = cur.execute(sql_param)
  43. exp_train = res.fetchone()
  44. cur.close()
  45. # connect device
  46. receiver = Receiver()
  47. config_info = settings.CONFIG_INFO
  48. receiver.select_connector(Device.NEO, 0.04, config_info)
  49. success = receiver.setup_connector()
  50. print(success)
  51. # begin to receive data from device.
  52. sleep(1)
  53. receiver.start_receive_wave()
  54. # --- Setup global variables (available in all functions) ---
  55. # Ensure that relative paths start from the same directory as this script
  56. _thisDir = os.path.dirname(os.path.abspath(__file__))
  57. # Store info about the experiment session
  58. psychopyVersion = '2023.2.3'
  59. expName = 'train' # from the Builder filename that created this script
  60. expInfo = {
  61. 'participant': f"{randint(0, 999999):06.0f}",
  62. 'session': '001',
  63. 'date': data.getDateStr(), # add a simple timestamp
  64. 'expName': expName,
  65. 'psychopyVersion': psychopyVersion,
  66. }
  67. def showExpInfoDlg(expInfo):
  68. """
  69. Show participant info dialog.
  70. Parameters
  71. ==========
  72. expInfo : dict
  73. Information about this experiment, created by the `setupExpInfo` function.
  74. Returns
  75. ==========
  76. dict
  77. Information about this experiment.
  78. """
  79. # temporarily remove keys which the dialog doesn't need to show
  80. poppedKeys = {
  81. 'date': expInfo.pop('date', data.getDateStr()),
  82. 'expName': expInfo.pop('expName', expName),
  83. 'psychopyVersion': expInfo.pop('psychopyVersion', psychopyVersion),
  84. }
  85. # show participant info dialog
  86. dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName)
  87. if dlg.OK == False:
  88. core.quit() # user pressed cancel
  89. # restore hidden keys
  90. expInfo.update(poppedKeys)
  91. # return expInfo
  92. return expInfo
  93. def setupData(expInfo, dataDir=None):
  94. """
  95. Make an ExperimentHandler to handle trials and saving.
  96. Parameters
  97. ==========
  98. expInfo : dict
  99. Information about this experiment, created by the `setupExpInfo` function.
  100. dataDir : Path, str or None
  101. Folder to save the data to, leave as None to create a folder in the current directory.
  102. Returns
  103. ==========
  104. psychopy.data.ExperimentHandler
  105. Handler object for this experiment, contains the data to save and information about
  106. where to save it to.
  107. """
  108. # data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
  109. if dataDir is None:
  110. dataDir = _thisDir
  111. filename = u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])
  112. # make sure filename is relative to dataDir
  113. if os.path.isabs(filename):
  114. dataDir = os.path.commonprefix([dataDir, filename])
  115. filename = os.path.relpath(filename, dataDir)
  116. # an ExperimentHandler isn't essential but helps with data saving
  117. thisExp = data.ExperimentHandler(
  118. name=expName, version='',
  119. extraInfo=expInfo, runtimeInfo=None,
  120. originPath='C:\\Users\\zhengyan\\Desktop\\back\\train\\train.py',
  121. savePickle=True, saveWideText=True,
  122. dataFileName=dataDir + os.sep + filename, sortColumns='time'
  123. )
  124. thisExp.setPriority('thisRow.t', priority.CRITICAL)
  125. thisExp.setPriority('expName', priority.LOW)
  126. # return experiment handler
  127. return thisExp
  128. def setupLogging(filename):
  129. """
  130. Setup a log file and tell it what level to log at.
  131. Parameters
  132. ==========
  133. filename : str or pathlib.Path
  134. Filename to save log file and data files as, doesn't need an extension.
  135. Returns
  136. ==========
  137. psychopy.logging.LogFile
  138. Text stream to receive inputs from the logging system.
  139. """
  140. # this outputs to the screen, not a file
  141. logging.console.setLevel(logging.EXP)
  142. # save a log file for detail verbose info
  143. logFile = logging.LogFile(filename+'.log', level=logging.EXP)
  144. return logFile
  145. def setupWindow(expInfo=None, win=None):
  146. """
  147. Setup the Window
  148. Parameters
  149. ==========
  150. expInfo : dict
  151. Information about this experiment, created by the `setupExpInfo` function.
  152. win : psychopy.visual.Window
  153. Window to setup - leave as None to create a new window.
  154. Returns
  155. ==========
  156. psychopy.visual.Window
  157. Window in which to run this experiment.
  158. """
  159. if win is None:
  160. # if not given a window to setup, make one
  161. win = visual.Window(
  162. size=(1024, 768), fullscr=True, screen=0,
  163. winType='pyglet', allowStencil=False,
  164. monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
  165. backgroundImage='', backgroundFit='none',
  166. blendMode='avg', useFBO=True,
  167. units='height'
  168. )
  169. if expInfo is not None:
  170. # store frame rate of monitor if we can measure it
  171. expInfo['frameRate'] = win.getActualFrameRate()
  172. else:
  173. # if we have a window, just set the attributes which are safe to set
  174. win.color = [0,0,0]
  175. win.colorSpace = 'rgb'
  176. win.backgroundImage = ''
  177. win.backgroundFit = 'none'
  178. win.units = 'height'
  179. win.mouseVisible = False
  180. win.hideMessage()
  181. return win
  182. def setupInputs(expInfo, thisExp, win):
  183. """
  184. Setup whatever inputs are available (mouse, keyboard, eyetracker, etc.)
  185. Parameters
  186. ==========
  187. expInfo : dict
  188. Information about this experiment, created by the `setupExpInfo` function.
  189. thisExp : psychopy.data.ExperimentHandler
  190. Handler object for this experiment, contains the data to save and information about
  191. where to save it to.
  192. win : psychopy.visual.Window
  193. Window in which to run this experiment.
  194. Returns
  195. ==========
  196. dict
  197. Dictionary of input devices by name.
  198. """
  199. # --- Setup input devices ---
  200. inputs = {}
  201. ioConfig = {}
  202. # Setup iohub keyboard
  203. ioConfig['Keyboard'] = dict(use_keymap='psychopy')
  204. ioSession = '1'
  205. if 'session' in expInfo:
  206. ioSession = str(expInfo['session'])
  207. ioServer = io.launchHubServer(window=win, **ioConfig)
  208. eyetracker = None
  209. # create a default keyboard (e.g. to check for escape)
  210. defaultKeyboard = keyboard.Keyboard(backend='iohub')
  211. # return inputs dict
  212. return {
  213. 'ioServer': ioServer,
  214. 'defaultKeyboard': defaultKeyboard,
  215. 'eyetracker': eyetracker,
  216. }
  217. def pauseExperiment(thisExp, inputs=None, win=None, timers=[], playbackComponents=[]):
  218. """
  219. Pause this experiment, preventing the flow from advancing to the next routine until resumed.
  220. Parameters
  221. ==========
  222. thisExp : psychopy.data.ExperimentHandler
  223. Handler object for this experiment, contains the data to save and information about
  224. where to save it to.
  225. inputs : dict
  226. Dictionary of input devices by name.
  227. win : psychopy.visual.Window
  228. Window for this experiment.
  229. timers : list, tuple
  230. List of timers to reset once pausing is finished.
  231. playbackComponents : list, tuple
  232. List of any components with a `pause` method which need to be paused.
  233. """
  234. # if we are not paused, do nothing
  235. if thisExp.status != PAUSED:
  236. return
  237. # pause any playback components
  238. for comp in playbackComponents:
  239. comp.pause()
  240. # prevent components from auto-drawing
  241. win.stashAutoDraw()
  242. # run a while loop while we wait to unpause
  243. while thisExp.status == PAUSED:
  244. # make sure we have a keyboard
  245. if inputs is None:
  246. inputs = {
  247. 'defaultKeyboard': keyboard.Keyboard(backend='ioHub')
  248. }
  249. # check for quit (typically the Esc key)
  250. if inputs['defaultKeyboard'].getKeys(keyList=['escape']):
  251. endExperiment(thisExp, win=win, inputs=inputs)
  252. # flip the screen
  253. win.flip()
  254. # if stop was requested while paused, quit
  255. if thisExp.status == FINISHED:
  256. endExperiment(thisExp, inputs=inputs, win=win)
  257. # resume any playback components
  258. for comp in playbackComponents:
  259. comp.play()
  260. # restore auto-drawn components
  261. win.retrieveAutoDraw()
  262. # reset any timers
  263. for timer in timers:
  264. timer.reset()
  265. def run(expInfo, thisExp, win, inputs, globalClock=None, thisSession=None):
  266. """
  267. Run the experiment flow.
  268. Parameters
  269. ==========
  270. expInfo : dict
  271. Information about this experiment, created by the `setupExpInfo` function.
  272. thisExp : psychopy.data.ExperimentHandler
  273. Handler object for this experiment, contains the data to save and information about
  274. where to save it to.
  275. psychopy.visual.Window
  276. Window in which to run this experiment.
  277. inputs : dict
  278. Dictionary of input devices by name.
  279. globalClock : psychopy.core.clock.Clock or None
  280. Clock to get global time from - supply None to make a new one.
  281. thisSession : psychopy.session.Session or None
  282. Handle of the Session object this experiment is being run from, if any.
  283. """
  284. # mark experiment as started
  285. thisExp.status = STARTED
  286. # make sure variables created by exec are available globally
  287. exec = environmenttools.setExecEnvironment(globals())
  288. # get device handles from dict of input devices
  289. ioServer = inputs['ioServer']
  290. defaultKeyboard = inputs['defaultKeyboard']
  291. eyetracker = inputs['eyetracker']
  292. # make sure we're running in the directory for this experiment
  293. os.chdir(_thisDir)
  294. # get filename from ExperimentHandler for convenience
  295. filename = thisExp.dataFileName
  296. frameTolerance = 0.001 # how close to onset before 'same' frame
  297. endExpNow = False # flag for 'escape' or other condition => quit the exp
  298. # get frame duration from frame rate in expInfo
  299. if 'frameRate' in expInfo and expInfo['frameRate'] is not None:
  300. frameDur = 1.0 / round(expInfo['frameRate'])
  301. else:
  302. frameDur = 1.0 / 60.0 # could not measure, so guess
  303. # Start Code - component code to be run after the window creation
  304. # --- Initialize components for Routine "exp_prepare" ---
  305. prepare = visual.TextStim(win=win, name='prepare',
  306. text='实验准备中...',
  307. font='Open Sans',
  308. pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
  309. color='white', colorSpace='rgb', opacity=None,
  310. languageStyle='LTR',
  311. depth=0.0);
  312. # --- Initialize components for Routine "before_mi" ---
  313. train_position = visual.TextStim(win=win, name='train_position',
  314. text="训练部位:" + exp_train[0],
  315. font='Open Sans',
  316. pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
  317. color='white', colorSpace='rgb', opacity=None,
  318. languageStyle='LTR',
  319. depth=0.0);
  320. instruction = visual.TextStim(win=win, name='instruction',
  321. text='静息态采集\n请保持放松,注视十字准星',
  322. font='Open Sans',
  323. pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
  324. color='white', colorSpace='rgb', opacity=None,
  325. languageStyle='LTR',
  326. depth=-1.0);
  327. img_reststate = visual.ImageStim(
  328. win=win,
  329. name='img_reststate',
  330. image='C:/Users/zhengyan/myWork/py_work/Kraken/Albatross/backend/static/images/reststate.png', mask=None, anchor='center',
  331. ori=0.0, pos=(0, 0), size=(0.5, 0.5),
  332. color=[1,1,1], colorSpace='rgb', opacity=None,
  333. flipHoriz=False, flipVert=False,
  334. texRes=128.0, interpolate=True, depth=-2.0)
  335. # --- Initialize components for Routine "mi_prepare" ---
  336. img_prepare = visual.ImageStim(
  337. win=win,
  338. name='img_prepare',
  339. image='C:/Users/zhengyan/myWork/py_work/Kraken/Albatross/backend/static/images/reststate.png', mask=None, anchor='center',
  340. ori=0.0, pos=(0, 0), size=(0.5, 0.5),
  341. color=[1,1,1], colorSpace='rgb', opacity=None,
  342. flipHoriz=False, flipVert=False,
  343. texRes=128.0, interpolate=True, depth=0.0)
  344. # --- Initialize components for Routine "mi_begin" ---
  345. img_right = visual.ImageStim(
  346. win=win,
  347. name='img_right',
  348. image='C:/Users/zhengyan/myWork/py_work/Kraken/Albatross/backend/static/images/right.png', mask=None, anchor='center',
  349. ori=0.0, pos=(0, 0), size=(0.5, 0.5),
  350. color=[1,1,1], colorSpace='rgb', opacity=None,
  351. flipHoriz=False, flipVert=False,
  352. texRes=128.0, interpolate=True, depth=0.0)
  353. # --- Initialize components for Routine "mi_feedback" ---
  354. feedback = visual.TextStim(win=win, name='feedback',
  355. text='反馈',
  356. font='Open Sans',
  357. pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
  358. color='white', colorSpace='rgb', opacity=None,
  359. languageStyle='LTR',
  360. depth=0.0);
  361. # --- Initialize components for Routine "mi_rest" ---
  362. img_rest = visual.ImageStim(
  363. win=win,
  364. name='img_rest',
  365. image='C:/Users/zhengyan/myWork/py_work/Kraken/Albatross/backend/static/images/rest.png', mask=None, anchor='center',
  366. ori=0.0, pos=(0, 0), size=(0.5, 0.5),
  367. color=[1,1,1], colorSpace='rgb', opacity=None,
  368. flipHoriz=False, flipVert=False,
  369. texRes=128.0, interpolate=True, depth=0.0)
  370. # --- Initialize components for Routine "end" ---
  371. mi_end = visual.TextStim(win=win, name='mi_end',
  372. text='结束实验',
  373. font='Open Sans',
  374. pos=(0, 0), height=0.05, wrapWidth=None, ori=0.0,
  375. color='white', colorSpace='rgb', opacity=None,
  376. languageStyle='LTR',
  377. depth=0.0);
  378. # create some handy timers
  379. if globalClock is None:
  380. globalClock = core.Clock() # to track the time since experiment started
  381. if ioServer is not None:
  382. ioServer.syncClock(globalClock)
  383. logging.setDefaultClock(globalClock)
  384. routineTimer = core.Clock() # to track time remaining of each (possibly non-slip) routine
  385. win.flip() # flip window to reset last flip timer
  386. # store the exact time the global clock started
  387. expInfo['expStart'] = data.getDateStr(format='%Y-%m-%d %Hh%M.%S.%f %z', fractionalSecondDigits=6)
  388. # --- Prepare to start Routine "exp_prepare" ---
  389. continueRoutine = True
  390. # update component parameters for each repeat
  391. thisExp.addData('exp_prepare.started', globalClock.getTime())
  392. # keep track of which components have finished
  393. exp_prepareComponents = [prepare]
  394. for thisComponent in exp_prepareComponents:
  395. thisComponent.tStart = None
  396. thisComponent.tStop = None
  397. thisComponent.tStartRefresh = None
  398. thisComponent.tStopRefresh = None
  399. if hasattr(thisComponent, 'status'):
  400. thisComponent.status = NOT_STARTED
  401. # reset timers
  402. t = 0
  403. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  404. frameN = -1
  405. # --- Run Routine "exp_prepare" ---
  406. routineForceEnded = not continueRoutine
  407. while continueRoutine and routineTimer.getTime() < 3.0:
  408. # get current time
  409. t = routineTimer.getTime()
  410. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  411. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  412. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  413. # update/draw components on each frame
  414. # *prepare* updates
  415. # if prepare is starting this frame...
  416. if prepare.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  417. # keep track of start time/frame for later
  418. prepare.frameNStart = frameN # exact frame index
  419. prepare.tStart = t # local t and not account for scr refresh
  420. prepare.tStartRefresh = tThisFlipGlobal # on global time
  421. win.timeOnFlip(prepare, 'tStartRefresh') # time at next scr refresh
  422. # add timestamp to datafile
  423. thisExp.timestampOnFlip(win, 'prepare.started')
  424. # update status
  425. prepare.status = STARTED
  426. prepare.setAutoDraw(True)
  427. # if prepare is active this frame...
  428. if prepare.status == STARTED:
  429. # update params
  430. pass
  431. # if prepare is stopping this frame...
  432. if prepare.status == STARTED:
  433. # is it time to stop? (based on global clock, using actual start)
  434. if tThisFlipGlobal > prepare.tStartRefresh + 3-frameTolerance:
  435. # keep track of stop time/frame for later
  436. prepare.tStop = t # not accounting for scr refresh
  437. prepare.frameNStop = frameN # exact frame index
  438. # add timestamp to datafile
  439. thisExp.timestampOnFlip(win, 'prepare.stopped')
  440. # update status
  441. prepare.status = FINISHED
  442. prepare.setAutoDraw(False)
  443. # check for quit (typically the Esc key)
  444. if defaultKeyboard.getKeys(keyList=["escape"]):
  445. thisExp.status = FINISHED
  446. if thisExp.status == FINISHED or endExpNow:
  447. endExperiment(thisExp, inputs=inputs, win=win)
  448. return
  449. # check if all components have finished
  450. if not continueRoutine: # a component has requested a forced-end of Routine
  451. routineForceEnded = True
  452. break
  453. continueRoutine = False # will revert to True if at least one component still running
  454. for thisComponent in exp_prepareComponents:
  455. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  456. continueRoutine = True
  457. break # at least one component has not yet finished
  458. # refresh the screen
  459. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  460. win.flip()
  461. # --- Ending Routine "exp_prepare" ---
  462. for thisComponent in exp_prepareComponents:
  463. if hasattr(thisComponent, "setAutoDraw"):
  464. thisComponent.setAutoDraw(False)
  465. thisExp.addData('exp_prepare.stopped', globalClock.getTime())
  466. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  467. if routineForceEnded:
  468. routineTimer.reset()
  469. else:
  470. routineTimer.addTime(-3.000000)
  471. # --- Prepare to start Routine "before_mi" ---
  472. continueRoutine = True
  473. # update component parameters for each repeat
  474. thisExp.addData('before_mi.started', globalClock.getTime())
  475. # keep track of which components have finished
  476. before_miComponents = [train_position, instruction, img_reststate]
  477. for thisComponent in before_miComponents:
  478. thisComponent.tStart = None
  479. thisComponent.tStop = None
  480. thisComponent.tStartRefresh = None
  481. thisComponent.tStopRefresh = None
  482. if hasattr(thisComponent, 'status'):
  483. thisComponent.status = NOT_STARTED
  484. # reset timers
  485. t = 0
  486. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  487. frameN = -1
  488. # --- Run Routine "before_mi" ---
  489. routineForceEnded = not continueRoutine
  490. while continueRoutine and routineTimer.getTime() < 16.5:
  491. # get current time
  492. t = routineTimer.getTime()
  493. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  494. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  495. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  496. # update/draw components on each frame
  497. # *train_position* updates
  498. # if train_position is starting this frame...
  499. if train_position.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  500. # keep track of start time/frame for later
  501. train_position.frameNStart = frameN # exact frame index
  502. train_position.tStart = t # local t and not account for scr refresh
  503. train_position.tStartRefresh = tThisFlipGlobal # on global time
  504. win.timeOnFlip(train_position, 'tStartRefresh') # time at next scr refresh
  505. # add timestamp to datafile
  506. thisExp.timestampOnFlip(win, 'train_position.started')
  507. # update status
  508. train_position.status = STARTED
  509. train_position.setAutoDraw(True)
  510. # if train_position is active this frame...
  511. if train_position.status == STARTED:
  512. # update params
  513. pass
  514. # if train_position is stopping this frame...
  515. if train_position.status == STARTED:
  516. # is it time to stop? (based on global clock, using actual start)
  517. if tThisFlipGlobal > train_position.tStartRefresh + 2-frameTolerance:
  518. # keep track of stop time/frame for later
  519. train_position.tStop = t # not accounting for scr refresh
  520. train_position.frameNStop = frameN # exact frame index
  521. # add timestamp to datafile
  522. thisExp.timestampOnFlip(win, 'train_position.stopped')
  523. # update status
  524. train_position.status = FINISHED
  525. train_position.setAutoDraw(False)
  526. # *instruction* updates
  527. # if instruction is starting this frame...
  528. if instruction.status == NOT_STARTED and tThisFlip >= 3-frameTolerance:
  529. # keep track of start time/frame for later
  530. instruction.frameNStart = frameN # exact frame index
  531. instruction.tStart = t # local t and not account for scr refresh
  532. instruction.tStartRefresh = tThisFlipGlobal # on global time
  533. win.timeOnFlip(instruction, 'tStartRefresh') # time at next scr refresh
  534. # add timestamp to datafile
  535. thisExp.timestampOnFlip(win, 'instruction.started')
  536. # update status
  537. instruction.status = STARTED
  538. instruction.setAutoDraw(True)
  539. # if instruction is active this frame...
  540. if instruction.status == STARTED:
  541. # update params
  542. pass
  543. # if instruction is stopping this frame...
  544. if instruction.status == STARTED:
  545. # is it time to stop? (based on global clock, using actual start)
  546. if tThisFlipGlobal > instruction.tStartRefresh + 2-frameTolerance:
  547. # keep track of stop time/frame for later
  548. instruction.tStop = t # not accounting for scr refresh
  549. instruction.frameNStop = frameN # exact frame index
  550. # add timestamp to datafile
  551. thisExp.timestampOnFlip(win, 'instruction.stopped')
  552. # update status
  553. instruction.status = FINISHED
  554. instruction.setAutoDraw(False)
  555. # *img_reststate* updates
  556. # if img_reststate is starting this frame...
  557. if img_reststate.status == NOT_STARTED and tThisFlip >= 6.5-frameTolerance:
  558. # keep track of start time/frame for later
  559. img_reststate.frameNStart = frameN # exact frame index
  560. img_reststate.tStart = t # local t and not account for scr refresh
  561. img_reststate.tStartRefresh = tThisFlipGlobal # on global time
  562. win.timeOnFlip(img_reststate, 'tStartRefresh') # time at next scr refresh
  563. # add timestamp to datafile
  564. thisExp.timestampOnFlip(win, 'img_reststate.started')
  565. # update status
  566. img_reststate.status = STARTED
  567. img_reststate.setAutoDraw(True)
  568. # if img_reststate is active this frame...
  569. if img_reststate.status == STARTED:
  570. # update params
  571. pass
  572. # if img_reststate is stopping this frame...
  573. if img_reststate.status == STARTED:
  574. # is it time to stop? (based on global clock, using actual start)
  575. if tThisFlipGlobal > img_reststate.tStartRefresh + 10-frameTolerance:
  576. # keep track of stop time/frame for later
  577. img_reststate.tStop = t # not accounting for scr refresh
  578. img_reststate.frameNStop = frameN # exact frame index
  579. # add timestamp to datafile
  580. thisExp.timestampOnFlip(win, 'img_reststate.stopped')
  581. # update status
  582. img_reststate.status = FINISHED
  583. img_reststate.setAutoDraw(False)
  584. # check for quit (typically the Esc key)
  585. if defaultKeyboard.getKeys(keyList=["escape"]):
  586. thisExp.status = FINISHED
  587. if thisExp.status == FINISHED or endExpNow:
  588. endExperiment(thisExp, inputs=inputs, win=win)
  589. return
  590. # check if all components have finished
  591. if not continueRoutine: # a component has requested a forced-end of Routine
  592. routineForceEnded = True
  593. break
  594. continueRoutine = False # will revert to True if at least one component still running
  595. for thisComponent in before_miComponents:
  596. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  597. continueRoutine = True
  598. break # at least one component has not yet finished
  599. # refresh the screen
  600. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  601. win.flip()
  602. # --- Ending Routine "before_mi" ---
  603. for thisComponent in before_miComponents:
  604. if hasattr(thisComponent, "setAutoDraw"):
  605. thisComponent.setAutoDraw(False)
  606. thisExp.addData('before_mi.stopped', globalClock.getTime())
  607. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  608. if routineForceEnded:
  609. routineTimer.reset()
  610. else:
  611. routineTimer.addTime(-16.500000)
  612. # set up handler to look after randomisation of conditions etc
  613. trials = data.TrialHandler(nReps=exp_train[1], method='random',
  614. extraInfo=expInfo, originPath=-1,
  615. trialList=[None],
  616. seed=None, name='trials')
  617. thisExp.addLoop(trials) # add the loop to the experiment
  618. thisTrial = trials.trialList[0] # so we can initialise stimuli with some values
  619. # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
  620. if thisTrial != None:
  621. for paramName in thisTrial:
  622. globals()[paramName] = thisTrial[paramName]
  623. for thisTrial in trials:
  624. currentLoop = trials
  625. thisExp.timestampOnFlip(win, 'thisRow.t')
  626. # pause experiment here if requested
  627. if thisExp.status == PAUSED:
  628. pauseExperiment(
  629. thisExp=thisExp,
  630. inputs=inputs,
  631. win=win,
  632. timers=[routineTimer],
  633. playbackComponents=[]
  634. )
  635. # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
  636. if thisTrial != None:
  637. for paramName in thisTrial:
  638. globals()[paramName] = thisTrial[paramName]
  639. # --- Prepare to start Routine "mi_prepare" ---
  640. continueRoutine = True
  641. # update component parameters for each repeat
  642. thisExp.addData('mi_prepare.started', globalClock.getTime())
  643. # keep track of which components have finished
  644. mi_prepareComponents = [img_prepare]
  645. for thisComponent in mi_prepareComponents:
  646. thisComponent.tStart = None
  647. thisComponent.tStop = None
  648. thisComponent.tStartRefresh = None
  649. thisComponent.tStopRefresh = None
  650. if hasattr(thisComponent, 'status'):
  651. thisComponent.status = NOT_STARTED
  652. # reset timers
  653. t = 0
  654. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  655. frameN = -1
  656. # --- Run Routine "mi_prepare" ---
  657. routineForceEnded = not continueRoutine
  658. while continueRoutine and routineTimer.getTime() < 1.5:
  659. # get current time
  660. t = routineTimer.getTime()
  661. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  662. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  663. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  664. # update/draw components on each frame
  665. # *img_prepare* updates
  666. # if img_prepare is starting this frame...
  667. if img_prepare.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  668. # keep track of start time/frame for later
  669. img_prepare.frameNStart = frameN # exact frame index
  670. img_prepare.tStart = t # local t and not account for scr refresh
  671. img_prepare.tStartRefresh = tThisFlipGlobal # on global time
  672. win.timeOnFlip(img_prepare, 'tStartRefresh') # time at next scr refresh
  673. # add timestamp to datafile
  674. thisExp.timestampOnFlip(win, 'img_prepare.started')
  675. # update status
  676. img_prepare.status = STARTED
  677. img_prepare.setAutoDraw(True)
  678. # if img_prepare is active this frame...
  679. if img_prepare.status == STARTED:
  680. # update params
  681. pass
  682. # if img_prepare is stopping this frame...
  683. if img_prepare.status == STARTED:
  684. # is it time to stop? (based on global clock, using actual start)
  685. if tThisFlipGlobal > img_prepare.tStartRefresh + 1.5-frameTolerance:
  686. # keep track of stop time/frame for later
  687. img_prepare.tStop = t # not accounting for scr refresh
  688. img_prepare.frameNStop = frameN # exact frame index
  689. # add timestamp to datafile
  690. thisExp.timestampOnFlip(win, 'img_prepare.stopped')
  691. # update status
  692. img_prepare.status = FINISHED
  693. img_prepare.setAutoDraw(False)
  694. # check for quit (typically the Esc key)
  695. if defaultKeyboard.getKeys(keyList=["escape"]):
  696. thisExp.status = FINISHED
  697. if thisExp.status == FINISHED or endExpNow:
  698. endExperiment(thisExp, inputs=inputs, win=win)
  699. return
  700. # check if all components have finished
  701. if not continueRoutine: # a component has requested a forced-end of Routine
  702. routineForceEnded = True
  703. break
  704. continueRoutine = False # will revert to True if at least one component still running
  705. for thisComponent in mi_prepareComponents:
  706. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  707. continueRoutine = True
  708. break # at least one component has not yet finished
  709. # refresh the screen
  710. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  711. win.flip()
  712. # --- Ending Routine "mi_prepare" ---
  713. for thisComponent in mi_prepareComponents:
  714. if hasattr(thisComponent, "setAutoDraw"):
  715. thisComponent.setAutoDraw(False)
  716. thisExp.addData('mi_prepare.stopped', globalClock.getTime())
  717. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  718. if routineForceEnded:
  719. routineTimer.reset()
  720. else:
  721. routineTimer.addTime(-1.500000)
  722. # --- Prepare to start Routine "mi_begin" ---
  723. continueRoutine = True
  724. # update component parameters for each repeat
  725. thisExp.addData('mi_begin.started', globalClock.getTime())
  726. # keep track of which components have finished
  727. mi_beginComponents = [img_right]
  728. for thisComponent in mi_beginComponents:
  729. thisComponent.tStart = None
  730. thisComponent.tStop = None
  731. thisComponent.tStartRefresh = None
  732. thisComponent.tStopRefresh = None
  733. if hasattr(thisComponent, 'status'):
  734. thisComponent.status = NOT_STARTED
  735. # reset timers
  736. t = 0
  737. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  738. frameN = -1
  739. # --- Run Routine "mi_begin" ---
  740. routineForceEnded = not continueRoutine
  741. while continueRoutine and routineTimer.getTime() < 5.0:
  742. # get current time
  743. t = routineTimer.getTime()
  744. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  745. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  746. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  747. # update/draw components on each frame
  748. # *img_right* updates
  749. # if img_right is starting this frame...
  750. if img_right.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  751. # keep track of start time/frame for later
  752. img_right.frameNStart = frameN # exact frame index
  753. img_right.tStart = t # local t and not account for scr refresh
  754. img_right.tStartRefresh = tThisFlipGlobal # on global time
  755. win.timeOnFlip(img_right, 'tStartRefresh') # time at next scr refresh
  756. # add timestamp to datafile
  757. thisExp.timestampOnFlip(win, 'img_right.started')
  758. # update status
  759. img_right.status = STARTED
  760. img_right.setAutoDraw(True)
  761. # if img_right is active this frame...
  762. if img_right.status == STARTED:
  763. # update params
  764. pass
  765. # if img_right is stopping this frame...
  766. if img_right.status == STARTED:
  767. # is it time to stop? (based on global clock, using actual start)
  768. if tThisFlipGlobal > img_right.tStartRefresh + 5-frameTolerance:
  769. # keep track of stop time/frame for later
  770. img_right.tStop = t # not accounting for scr refresh
  771. img_right.frameNStop = frameN # exact frame index
  772. # add timestamp to datafile
  773. thisExp.timestampOnFlip(win, 'img_right.stopped')
  774. # update status
  775. img_right.status = FINISHED
  776. img_right.setAutoDraw(False)
  777. # check for quit (typically the Esc key)
  778. if defaultKeyboard.getKeys(keyList=["escape"]):
  779. thisExp.status = FINISHED
  780. if thisExp.status == FINISHED or endExpNow:
  781. endExperiment(thisExp, inputs=inputs, win=win)
  782. return
  783. # check if all components have finished
  784. if not continueRoutine: # a component has requested a forced-end of Routine
  785. routineForceEnded = True
  786. break
  787. continueRoutine = False # will revert to True if at least one component still running
  788. for thisComponent in mi_beginComponents:
  789. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  790. continueRoutine = True
  791. break # at least one component has not yet finished
  792. # refresh the screen
  793. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  794. win.flip()
  795. # --- Ending Routine "mi_begin" ---
  796. for thisComponent in mi_beginComponents:
  797. if hasattr(thisComponent, "setAutoDraw"):
  798. thisComponent.setAutoDraw(False)
  799. thisExp.addData('mi_begin.stopped', globalClock.getTime())
  800. # Run 'End Routine' code from algo
  801. # get data
  802. data_from_buffer = receiver.get_data_from_buffer("classify_online")
  803. if data_from_buffer["status"] == "ok":
  804. raw_waves = data_from_buffer["data"].get_data()
  805. timestamps = data_from_buffer["timestamp"]
  806. # your process method ex:predict = pipeline(data)
  807. predict = 1
  808. if predict == 1:
  809. # 气动手指令
  810. feedback_time = 15
  811. elif predict == 0:
  812. # 气动手指令
  813. feedback_time = 2
  814. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  815. if routineForceEnded:
  816. routineTimer.reset()
  817. else:
  818. routineTimer.addTime(-5.000000)
  819. # --- Prepare to start Routine "mi_feedback" ---
  820. continueRoutine = True
  821. # update component parameters for each repeat
  822. thisExp.addData('mi_feedback.started', globalClock.getTime())
  823. # keep track of which components have finished
  824. mi_feedbackComponents = [feedback]
  825. for thisComponent in mi_feedbackComponents:
  826. thisComponent.tStart = None
  827. thisComponent.tStop = None
  828. thisComponent.tStartRefresh = None
  829. thisComponent.tStopRefresh = None
  830. if hasattr(thisComponent, 'status'):
  831. thisComponent.status = NOT_STARTED
  832. # reset timers
  833. t = 0
  834. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  835. frameN = -1
  836. # --- Run Routine "mi_feedback" ---
  837. routineForceEnded = not continueRoutine
  838. while continueRoutine:
  839. # get current time
  840. t = routineTimer.getTime()
  841. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  842. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  843. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  844. # update/draw components on each frame
  845. # *feedback* updates
  846. # if feedback is starting this frame...
  847. if feedback.status == NOT_STARTED and tThisFlip >= 0-frameTolerance:
  848. # keep track of start time/frame for later
  849. feedback.frameNStart = frameN # exact frame index
  850. feedback.tStart = t # local t and not account for scr refresh
  851. feedback.tStartRefresh = tThisFlipGlobal # on global time
  852. win.timeOnFlip(feedback, 'tStartRefresh') # time at next scr refresh
  853. # add timestamp to datafile
  854. thisExp.timestampOnFlip(win, 'feedback.started')
  855. # update status
  856. feedback.status = STARTED
  857. feedback.setAutoDraw(True)
  858. # if feedback is active this frame...
  859. if feedback.status == STARTED:
  860. # update params
  861. pass
  862. # if feedback is stopping this frame...
  863. if feedback.status == STARTED:
  864. # is it time to stop? (based on global clock, using actual start)
  865. if tThisFlipGlobal > feedback.tStartRefresh + feedback_time-frameTolerance:
  866. # keep track of stop time/frame for later
  867. feedback.tStop = t # not accounting for scr refresh
  868. feedback.frameNStop = frameN # exact frame index
  869. # add timestamp to datafile
  870. thisExp.timestampOnFlip(win, 'feedback.stopped')
  871. # update status
  872. feedback.status = FINISHED
  873. feedback.setAutoDraw(False)
  874. # check for quit (typically the Esc key)
  875. if defaultKeyboard.getKeys(keyList=["escape"]):
  876. thisExp.status = FINISHED
  877. if thisExp.status == FINISHED or endExpNow:
  878. endExperiment(thisExp, inputs=inputs, win=win)
  879. return
  880. # check if all components have finished
  881. if not continueRoutine: # a component has requested a forced-end of Routine
  882. routineForceEnded = True
  883. break
  884. continueRoutine = False # will revert to True if at least one component still running
  885. for thisComponent in mi_feedbackComponents:
  886. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  887. continueRoutine = True
  888. break # at least one component has not yet finished
  889. # refresh the screen
  890. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  891. win.flip()
  892. # --- Ending Routine "mi_feedback" ---
  893. for thisComponent in mi_feedbackComponents:
  894. if hasattr(thisComponent, "setAutoDraw"):
  895. thisComponent.setAutoDraw(False)
  896. thisExp.addData('mi_feedback.stopped', globalClock.getTime())
  897. # the Routine "mi_feedback" was not non-slip safe, so reset the non-slip timer
  898. routineTimer.reset()
  899. # --- Prepare to start Routine "mi_rest" ---
  900. continueRoutine = True
  901. # update component parameters for each repeat
  902. thisExp.addData('mi_rest.started', globalClock.getTime())
  903. # keep track of which components have finished
  904. mi_restComponents = [img_rest]
  905. for thisComponent in mi_restComponents:
  906. thisComponent.tStart = None
  907. thisComponent.tStop = None
  908. thisComponent.tStartRefresh = None
  909. thisComponent.tStopRefresh = None
  910. if hasattr(thisComponent, 'status'):
  911. thisComponent.status = NOT_STARTED
  912. # reset timers
  913. t = 0
  914. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  915. frameN = -1
  916. # --- Run Routine "mi_rest" ---
  917. routineForceEnded = not continueRoutine
  918. while continueRoutine and routineTimer.getTime() < 5.0:
  919. # get current time
  920. t = routineTimer.getTime()
  921. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  922. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  923. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  924. # update/draw components on each frame
  925. # *img_rest* updates
  926. # if img_rest is starting this frame...
  927. if img_rest.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  928. # keep track of start time/frame for later
  929. img_rest.frameNStart = frameN # exact frame index
  930. img_rest.tStart = t # local t and not account for scr refresh
  931. img_rest.tStartRefresh = tThisFlipGlobal # on global time
  932. win.timeOnFlip(img_rest, 'tStartRefresh') # time at next scr refresh
  933. # add timestamp to datafile
  934. thisExp.timestampOnFlip(win, 'img_rest.started')
  935. # update status
  936. img_rest.status = STARTED
  937. img_rest.setAutoDraw(True)
  938. # if img_rest is active this frame...
  939. if img_rest.status == STARTED:
  940. # update params
  941. pass
  942. # if img_rest is stopping this frame...
  943. if img_rest.status == STARTED:
  944. # is it time to stop? (based on global clock, using actual start)
  945. if tThisFlipGlobal > img_rest.tStartRefresh + 5-frameTolerance:
  946. # keep track of stop time/frame for later
  947. img_rest.tStop = t # not accounting for scr refresh
  948. img_rest.frameNStop = frameN # exact frame index
  949. # add timestamp to datafile
  950. thisExp.timestampOnFlip(win, 'img_rest.stopped')
  951. # update status
  952. img_rest.status = FINISHED
  953. img_rest.setAutoDraw(False)
  954. # check for quit (typically the Esc key)
  955. if defaultKeyboard.getKeys(keyList=["escape"]):
  956. thisExp.status = FINISHED
  957. if thisExp.status == FINISHED or endExpNow:
  958. endExperiment(thisExp, inputs=inputs, win=win)
  959. return
  960. # check if all components have finished
  961. if not continueRoutine: # a component has requested a forced-end of Routine
  962. routineForceEnded = True
  963. break
  964. continueRoutine = False # will revert to True if at least one component still running
  965. for thisComponent in mi_restComponents:
  966. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  967. continueRoutine = True
  968. break # at least one component has not yet finished
  969. # refresh the screen
  970. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  971. win.flip()
  972. # --- Ending Routine "mi_rest" ---
  973. for thisComponent in mi_restComponents:
  974. if hasattr(thisComponent, "setAutoDraw"):
  975. thisComponent.setAutoDraw(False)
  976. thisExp.addData('mi_rest.stopped', globalClock.getTime())
  977. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  978. if routineForceEnded:
  979. routineTimer.reset()
  980. else:
  981. routineTimer.addTime(-5.000000)
  982. thisExp.nextEntry()
  983. if thisSession is not None:
  984. # if running in a Session with a Liaison client, send data up to now
  985. thisSession.sendExperimentData()
  986. # completed exp_train[1] repeats of 'trials'
  987. # --- Prepare to start Routine "end" ---
  988. continueRoutine = True
  989. # update component parameters for each repeat
  990. thisExp.addData('end.started', globalClock.getTime())
  991. # keep track of which components have finished
  992. endComponents = [mi_end]
  993. for thisComponent in endComponents:
  994. thisComponent.tStart = None
  995. thisComponent.tStop = None
  996. thisComponent.tStartRefresh = None
  997. thisComponent.tStopRefresh = None
  998. if hasattr(thisComponent, 'status'):
  999. thisComponent.status = NOT_STARTED
  1000. # reset timers
  1001. t = 0
  1002. _timeToFirstFrame = win.getFutureFlipTime(clock="now")
  1003. frameN = -1
  1004. # --- Run Routine "end" ---
  1005. routineForceEnded = not continueRoutine
  1006. while continueRoutine and routineTimer.getTime() < 5.0:
  1007. # get current time
  1008. t = routineTimer.getTime()
  1009. tThisFlip = win.getFutureFlipTime(clock=routineTimer)
  1010. tThisFlipGlobal = win.getFutureFlipTime(clock=None)
  1011. frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
  1012. # update/draw components on each frame
  1013. # *mi_end* updates
  1014. # if mi_end is starting this frame...
  1015. if mi_end.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
  1016. # keep track of start time/frame for later
  1017. mi_end.frameNStart = frameN # exact frame index
  1018. mi_end.tStart = t # local t and not account for scr refresh
  1019. mi_end.tStartRefresh = tThisFlipGlobal # on global time
  1020. win.timeOnFlip(mi_end, 'tStartRefresh') # time at next scr refresh
  1021. # add timestamp to datafile
  1022. thisExp.timestampOnFlip(win, 'mi_end.started')
  1023. # update status
  1024. mi_end.status = STARTED
  1025. mi_end.setAutoDraw(True)
  1026. # if mi_end is active this frame...
  1027. if mi_end.status == STARTED:
  1028. # update params
  1029. pass
  1030. # if mi_end is stopping this frame...
  1031. if mi_end.status == STARTED:
  1032. # is it time to stop? (based on global clock, using actual start)
  1033. if tThisFlipGlobal > mi_end.tStartRefresh + 5-frameTolerance:
  1034. # keep track of stop time/frame for later
  1035. mi_end.tStop = t # not accounting for scr refresh
  1036. mi_end.frameNStop = frameN # exact frame index
  1037. # add timestamp to datafile
  1038. thisExp.timestampOnFlip(win, 'mi_end.stopped')
  1039. # update status
  1040. mi_end.status = FINISHED
  1041. mi_end.setAutoDraw(False)
  1042. # check for quit (typically the Esc key)
  1043. if defaultKeyboard.getKeys(keyList=["escape"]):
  1044. thisExp.status = FINISHED
  1045. if thisExp.status == FINISHED or endExpNow:
  1046. endExperiment(thisExp, inputs=inputs, win=win)
  1047. return
  1048. # check if all components have finished
  1049. if not continueRoutine: # a component has requested a forced-end of Routine
  1050. routineForceEnded = True
  1051. break
  1052. continueRoutine = False # will revert to True if at least one component still running
  1053. for thisComponent in endComponents:
  1054. if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
  1055. continueRoutine = True
  1056. break # at least one component has not yet finished
  1057. # refresh the screen
  1058. if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
  1059. win.flip()
  1060. # --- Ending Routine "end" ---
  1061. for thisComponent in endComponents:
  1062. if hasattr(thisComponent, "setAutoDraw"):
  1063. thisComponent.setAutoDraw(False)
  1064. thisExp.addData('end.stopped', globalClock.getTime())
  1065. # using non-slip timing so subtract the expected duration of this Routine (unless ended on request)
  1066. if routineForceEnded:
  1067. routineTimer.reset()
  1068. else:
  1069. routineTimer.addTime(-5.000000)
  1070. # Run 'End Experiment' code from code
  1071. receiver.stop_receive()
  1072. # mark experiment as finished
  1073. endExperiment(thisExp, win=win, inputs=inputs)
  1074. def saveData(thisExp):
  1075. """
  1076. Save data from this experiment
  1077. Parameters
  1078. ==========
  1079. thisExp : psychopy.data.ExperimentHandler
  1080. Handler object for this experiment, contains the data to save and information about
  1081. where to save it to.
  1082. """
  1083. filename = thisExp.dataFileName
  1084. # these shouldn't be strictly necessary (should auto-save)
  1085. thisExp.saveAsWideText(filename + '.csv', delim='auto')
  1086. thisExp.saveAsPickle(filename)
  1087. def endExperiment(thisExp, inputs=None, win=None):
  1088. """
  1089. End this experiment, performing final shut down operations.
  1090. This function does NOT close the window or end the Python process - use `quit` for this.
  1091. Parameters
  1092. ==========
  1093. thisExp : psychopy.data.ExperimentHandler
  1094. Handler object for this experiment, contains the data to save and information about
  1095. where to save it to.
  1096. inputs : dict
  1097. Dictionary of input devices by name.
  1098. win : psychopy.visual.Window
  1099. Window for this experiment.
  1100. """
  1101. if win is not None:
  1102. # remove autodraw from all current components
  1103. win.clearAutoDraw()
  1104. # Flip one final time so any remaining win.callOnFlip()
  1105. # and win.timeOnFlip() tasks get executed
  1106. win.flip()
  1107. # mark experiment handler as finished
  1108. thisExp.status = FINISHED
  1109. # shut down eyetracker, if there is one
  1110. if inputs is not None:
  1111. if 'eyetracker' in inputs and inputs['eyetracker'] is not None:
  1112. inputs['eyetracker'].setConnectionState(False)
  1113. logging.flush()
  1114. def quit(thisExp, win=None, inputs=None, thisSession=None):
  1115. """
  1116. Fully quit, closing the window and ending the Python process.
  1117. Parameters
  1118. ==========
  1119. win : psychopy.visual.Window
  1120. Window to close.
  1121. inputs : dict
  1122. Dictionary of input devices by name.
  1123. thisSession : psychopy.session.Session or None
  1124. Handle of the Session object this experiment is being run from, if any.
  1125. """
  1126. thisExp.abort() # or data files will save again on exit
  1127. # make sure everything is closed down
  1128. if win is not None:
  1129. # Flip one final time so any remaining win.callOnFlip()
  1130. # and win.timeOnFlip() tasks get executed before quitting
  1131. win.flip()
  1132. win.close()
  1133. if inputs is not None:
  1134. if 'eyetracker' in inputs and inputs['eyetracker'] is not None:
  1135. inputs['eyetracker'].setConnectionState(False)
  1136. logging.flush()
  1137. if thisSession is not None:
  1138. thisSession.stop()
  1139. # terminate Python process
  1140. core.quit()
  1141. # if running this experiment as a script...
  1142. if __name__ == '__main__':
  1143. # call all functions in order
  1144. expInfo = showExpInfoDlg(expInfo=expInfo)
  1145. thisExp = setupData(expInfo=expInfo)
  1146. logFile = setupLogging(filename=thisExp.dataFileName)
  1147. win = setupWindow(expInfo=expInfo)
  1148. inputs = setupInputs(expInfo=expInfo, thisExp=thisExp, win=win)
  1149. run(
  1150. expInfo=expInfo,
  1151. thisExp=thisExp,
  1152. win=win,
  1153. inputs=inputs
  1154. )
  1155. saveData(thisExp=thisExp)
  1156. quit(thisExp=thisExp, win=win, inputs=inputs)