在这个PsychoPy 教程中,你将学习如何使用一些但不是很多的编码来创建 精神运动警觉性任务(PVT)。但是请注意,由于这个测试的设置有一个随机的刺激间期(ISI),我们将创建一个具有我们想要的持续时间的精神运动警觉性测试,我们将提出反馈,我们也必须使用一些自定义的Python代码。在这个Psychopy教程的下一节,你会发现以下信息:1)你需要什么来遵循这个教程;2)这个帖子的内容概述。如果你只想下载Psychomotor任务,你可以点击这里获取说明。
前提条件和大纲
当然,要学习这个PsychoPy教程,你需要有一个已安装的PsychoPy版本和一些最基本的Python语言知识(如果你想对你的实验进行一些定制)。要下载并找到关于如何安装PsychoPy的说明,请点击这里。在这篇文章中,我们将使用PsychoPy创建精神运动警觉性任务。我们将通过如何创建例程、添加文本刺激、键盘反应和自定义Python代码等内容。
如何用PsychoPy创建一个精神运动警觉性任务
在本节中,我们将首先打开PsychoPy应用程序,然后逐步建立心理运动警觉性测试。在这篇文章中,我们使用PsychoPy 2022.1.4版本:
创建精神运动警觉性测试的任务说明
首先,当我们启动PsychoPy时,我们会得到一个名为 "trial "的例程(见上图)。这里我们将删除这个例程,然后将 "untitled.psyexp "保存为PVT。要删除试用例程,我们右击它,并从下拉菜单中选择 "删除":
接下来要做的是保存实验,并(同时)给它一个名字。在PsychoPy中保存实验的方法与其他大多数应用程序一样。首先,我们点击 "文件",然后点击 "保存为...":
在这个PsychoPy教程中,我们正在创建一个精神运动警觉性测试,所以我们把实验保存为 "PVT.psyexp"。注意,这也会给实验取名为 "PVT"。然而,你可以在实验设置中改变实验的名称:
PsychoPy实验设置
现在,我们将保留这个名字,但我们将在文章的后面看一下实验设置。在下一节中,我们将开始在PsychoPy中构建测试,添加一个包含任务说明的欢迎屏幕。
创建第一个例程。指令
在本小节中,我们将创建第一个包含任务说明的例程。首先,我们点击PsychoPy左角的 "插入例程":
点击"(new)"后,会弹出一个对话。在这里,我们将新的例程命名为 "指令",然后按 "确定":
现在我们有了我们的例程,我们将添加两个组件。文本和键盘。PsychoPy的组件在Routine的右边。我们将在Stimuli下面的Text组件中开始添加指令:
在本教程中,我们不会对这个文本组件做太多的添加和修改。基本上,我们将添加它,并将其名称改为 "OrditionsText",并删除持续时间(我们将留空)。最后,我们要添加这个指令的文本:
说明
欢迎!
在这个任务中,你要在屏幕上出现红色计数器后尽快按下空格键,
。
按空格键开始执行任务。
对了,现在我们有一些任务说明,但是你可以看到在说明的最后,我们告诉参与者要按空格键来开始任务。这意味着我们需要添加一个键盘组件。同样,我们可以在PsychoPy构建器中的右侧找到我们想要的组件(在 "响应 "下):
正如你在上图中看到的,我们将键盘组件命名为 "InstrucKey",然后删除了除 "空格 "以外的所有内容。在下一节,我们准备开始创建任务。
刺激间期
我们要做的下一件事是固定刺激间期(ISI)。在这里,我们将创建我们的第一个自定义代码。 首先,我们创建一个PsychoPy例程并将其命名为 "ISI"。 其次,我们找到我们的代码组件。同样,我们可以在PsychoPy Builder GUI的右侧 "Custom "下找到它。 我们把这个例程命名为 "ISIcode"。 现在你可能已经看到了,有许多不同的标签。在本教程的这一部分,我们将在 "开始实验"、"开始例程 "和 "每个帧 "中添加代码。 这里有一张图片显示了所有的内容:
不要担心,我们会比这更详细地介绍(另外,你可以在文章末尾下载心理运动警觉性任务来看看)。 在第一个标签("正在实验")中,我们将添加精神运动警觉性测试的一些设置:ISI、任务的持续时间和任务的持续时间。当然,我们可以在以前的例程中把这些添加到一个代码组件中,但那时我们对其他代码段没有用处。下面是我们添加的代码:
# All the durations are in seconds
# Random ISI between 1 and 4.
minISI = 1
maxISI = 4
# Task duration
length_of_task = 180
# Feedback duration
feed = 0.5
# A timer
timing = core.Clock()
# Loading the beep sound
warning_beep = sound.Sound('beep.wav')
Code language: Python (python)
请注意,所有的持续时间都是以秒为单位的,所以这个精神运动警觉性任务可能相当短(即3分钟),你可以根据自己的需要改变这个时间。希望这些变量名称相当不言自明(连同代码中的注释),但它是ISI、反馈的持续时间和任务。最后两个变量在这个特定的例程中没有使用,但我们将使用一个警告声(哔哔声),在没有反应时播放(定时器也用于此)。在下一个选项卡("开始例程")中,我们将添加每次启动该例程时都会改变的代码:
# ISI is then set each routine
randISI = random() * (maxISI - minISI) + minISI
# If it is the first trial
if PVT_Trials.thisN == 0:
overall_timer = core.Clock()
realISI = 0
if PVT_Trials.thisN > 0:
# We count the duration of the feedback as part of the ISI
realISI = feed
# A message when participant miss
message = 'You did not hit the button!'
# Adding the ISI so it is saved in the datafile
thisExp.addData('ISI', randISI)
Code language: Python (python)
在上面的代码中,我们首先计算每个试验(即每个例程)的随机ISI。在第5-7行,我们设置了一个定时器,然后将一个变量设置为0。现在,我们将在以后使用这个变量(在第7行),但是从第二次试验到最后一次试验,我们从随机ISI中减去反馈持续时间。这样,我们就把反馈包括在ISI中。如果你不想把反馈持续时间计入ISI,可以删除第5-11行。最后,我们还要添加要不断运行(即更新)的代码:
keys = dontrespond.getKeys(keyList=['space'], waitRelease=False)
keys = [key.name for key in keys]
# Append True to list if a key is pressed, clear list if not
if "space" in keys:
message = "Too soon!"
continueRoutine = False
Code language: Python (python)
上面的代码保证了当参与者太快的时候(比如说抓住机会),反应时间不会被记录下来,他们会收到反馈,告诉他们他们太快了接下来要做的是添加一个文本组件(基本上就是一个空白屏幕):
在这个文本组件中,我们使用一些我们之前在代码组件中创建的变量。这里我们使用随机ISI,但我们减去了反馈时间。另外,请注意我们把 "文本 "留为空白。现在,我们还需要添加最后一样东西,以使ISI程序完整:一个键盘响应。
在精神运动警觉性任务中添加目标
在本小节中,我们将添加一个包含目标(即精神运动警觉性测试中的计数器)的例程。当我们创建了新的程序(称为 "目标"),我们将添加1)自定义代码,2)文本刺激,和3)键盘。 下面是我们添加的代码(开始例程标签)。
# Reset the timer
timing.reset()
# Check for response
if message == 'Too soon!':
# Adding 0 to Accuracy and missing to RTms
thisExp.addData('Accuracy', 0)
thisExp.addData('RTms', np.NAN)
# End the Routine to continue next trial
continueRoutine = False
Code language: PHP (php)
首先,我们重置之前创建的计时器,使参与者从目标开始有30秒的反应时间。第二,我们检查是否有反应。在这个if-statement中,我们还添加了一些数据。我们还将在 "每帧 "标签中添加一行代码。 time = int(round(timing.getTime(), 3) * 1000).
为了使反馈(见下一节)成为实际的反应时间,我们还需要在 "结束常规 "标签中添加代码。在下面的代码块中,我们要确保Response.rt实际上是浮动的(也就是如果我们得到了反应)。然后我们将消息改为反应时间,并将准确性和反应时间以毫秒为单位添加到数据中。在最后一个if语句中,我们确保反馈被改为 "没有反应"!并且我们再次将数据添加到文件中,以及播放一个警告声音。
if type(Response.rt) is float:
message = str(round(Response.rt * 1000))
thisExp.addData('Accuracy', 1)
thisExp.addData('RTms', Response.rt * 1000)
# PsychoPy is not running the trial for more than 29.991...
if timing.getTime() >= 29.99:
message = 'No response!'
warning_beep.play()
Response.rt = timing.getTime()
thisExp.addData('RTms', np.NAN)
thisExp.addData('Accuracy', 0)
continueRoutine = False
Code language: PHP (php)
接下来是添加目标刺激物:
注意,我们在文本字段中添加了$time,但也从 "常数 "改为 "每帧设置"。 这是因为这个变量将是时间计数(即目标)。这里我们还将通过点击外观标签将计数器的颜色改为红色。我们把前景颜色改为红色:
接下来要做的事情是添加一个键盘组件来收集响应:
在下一节中,我们将创建一个用于显示反馈的例程。
反馈
在这个小节中,我们将学习如何向精神运动警觉性任务添加反馈。我们只需通过创建一个新的例程并向其添加一个文本组件来实现:
请注意,我们只向这个组件添加变量,并在每次重复时将其改为设置(信息需要在每次运行这个例程时改变)。还记得前面的代码块吗?嗯,反馈持续时间是在PsychoPy教程的前面设置的,消息要么是反应时间,要么是他们反应过快,要么是他们没有反应。如果你想让反馈显示为红色,记得在外观选项卡中修改。在下一小节中,我们将添加一个循环,一个我们称之为 "End_task "的新例程,以及一个用于显示通知任务完成的文本的例程。
创建一个循环并最终完成实验
在本小节中,我们首先添加我们称之为 "End_task "的例程,它只包含几行 Python 代码:
# Get the time in the task
time_in_task = overall_timer.getTime()
# If time_in_task corresponds to the duration we set previously we end te task
if time_in_task >= length_of_task:
continueRoutine = False
PVT_Trials.finished = True
Code language: PHP (php)
注意,最后一行(7)使用了我们没有创建的东西:试验循环。下面是我们创建这个循环的方法(现在,重要的是我们把它命名为 "PVT_Trials")。首先,我们点击 "插入循环":
接下来,我们将通过以下方式添加循环:1)点击 "指令 "和 "ISI "之间的流程。循环应该在 "End_task "之后结束,所以接下来,我们点击那里。我们添加120次重复,因为无论如何,实验将在一定的时间后结束。再次记住给这个循环命名为 "PVT_Trials":
现在我们在试行任务之前还有最后一件事要做!我们将添加最后一个例程,包含一个文本刺激(有一些文本通知参与者任务已经完成)和一个键盘组件来结束任务:
关于键盘组件,没有什么特别的,但我们要给它一个名字,删除除空格外的所有按键,并确保没有持续时间:
现在你应该有一个用PsychoPy创建的正在运行的心理运动任务。下面是你的Flow应该是什么样子的:
改变PsychoPy的背景颜色
我们可以做的最后一件事是在实验设置中把背景颜色改为黑色(或者任何我们想要的颜色):
现在你应该有一个正在运行的精神运动警觉性任务。请确保你的试点测试,并检查文件中的数据是否看起来没问题。如果你想学习如何处理数据(一般来说),这里有一些帖子
下载用PsychoPy创建的精神运动警觉性测试(PVT)
在这个PsychoPy教程中创建的精神运动警觉性测试可以从这个GitHub页面下载。我创建的大多数实验任务都是在CC-BY许可下发布的,所以请确保你给我的信用。例如,最好是在参考文献中使用这篇博文。关于这方面的更多信息可以在README中找到。最后,如果你对这个文件有任何问题--请在GitHub上开一个问题。
结论
注意,这个任务是用PsychoPy 2022.1.4创建的。尽管当PsychoPy的新版本发布时,我会尽量不定期地更新帖子,但如果你能让我知道任何问题,我将不胜感激。最后,如果你欣赏我的帖子,请在这里或这里捐款。























