psychopy.org | Reference | Downloads | Github

Setting up trigger codes in a loop-in-loop lexical decision task

Hi,

I am working on a lexical decision task in which multiple lists of words are randomly selected similarly to what suggested here.

Essentially, one loop trial is built inside of another block, in order to allow the program to pick a list of words randomly, and then randomly present the words contained in that list.

What I I am trying to do now, is setting up trigger codes for the words. To do that, I need to refer to the trigger codes that are in the trigger column of each of the wordlist csv files.

However, I can’t find a way to do that in the Coder. Here is a excerpt of my code, in case it helps.

# set up handler to look after randomisation of conditions etc
blocks = data.TrialHandler(nReps=1, method='random', 
    extraInfo=expInfo, originPath=-1,
    trialList=data.importConditions('conditions.csv'),
    seed=None, name='blocks')
thisExp.addLoop(blocks)  # add the loop to the experiment
thisBlock = blocks.trialList[0]  # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
if thisBlock != None:
    for paramName in thisBlock.keys():
        exec(paramName + '= thisBlock.' + paramName)

for thisBlock in blocks:
    currentLoop = blocks
    # abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
    if thisBlock != None:
        for paramName in thisBlock.keys():
            exec(paramName + '= thisBlock.' + paramName)
    
    # set up handler to look after randomisation of conditions etc
    trials = data.TrialHandler(nReps=1, method='random', 
        extraInfo=expInfo, originPath=-1,
        trialList=data.importConditions(conditions_file),
        seed=None, name='trials')
    thisExp.addLoop(trials)  # add the loop to the experiment
    thisTrial = trials.trialList[0]  # so we can initialise stimuli with some values
    # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
    if thisTrial != None:
        for paramName in thisTrial.keys():
            exec(paramName + '= thisTrial.' + paramName)
    
    for thisTrial in trials:
        currentLoop = trials
        # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
        if thisTrial != None:
            for paramName in thisTrial.keys():
                exec(paramName + '= thisTrial.' + paramName)

# ------Prepare to start Routine "TRIAL"-------
        t = 0
        TRIALClock.reset()  # clock
        frameN = -1
        continueRoutine = True
        # update component parameters for each repeat
        trial_text.setText(word)
        trial_resp = event.BuilderKeyResponse()
        
        # keep track of which components have finished
        TRIALComponents = [trial_text, trial_resp]
        for thisComponent in TRIALComponents:
            if hasattr(thisComponent, 'status'):
                thisComponent.status = NOT_STARTED
        
        # -------Start Routine "TRIAL"-------
        while continueRoutine:
            # get current time
            t = TRIALClock.getTime()
            frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
            # update/draw components on each frame
            
            # *trial_text* updates
            if t >= 0.0 and trial_text.status == NOT_STARTED:
                # keep track of start time/frame for later
                trial_text.tStart = t
                trial_text.frameNStart = frameN  # exact frame index
                trial_text.setAutoDraw(True)
            frameRemains = 0.0 + .300- win.monitorFramePeriod * 0.75  # most of one frame period left
            if trial_text.status == STARTED and t >= frameRemains:
                trial_text.setAutoDraw(False)
            
            # *trial_resp* updates
            if t >= 0.0 and trial_resp.status == NOT_STARTED:
                # keep track of start time/frame for later
                trial_resp.tStart = t
                trial_resp.frameNStart = frameN  # exact frame index
                trial_resp.status = STARTED
                # keyboard checking is just starting
                win.callOnFlip(trial_resp.clock.reset)  # t=0 on next screen flip
                event.clearEvents(eventType='keyboard')
            if trial_resp.status == STARTED:
                theseKeys = event.getKeys(keyList=['f', 'j'])
            
                
                # check for quit:
                if "escape" in theseKeys:
                    endExpNow = True
                if len(theseKeys) > 0:  # at least one key was pressed
                    trial_resp.keys = theseKeys[-1]  # just the last key pressed
                    trial_resp.rt = trial_resp.clock.getTime()
                    # was this 'correct'?
                    if (trial_resp.keys == str(corrAns)) or (trial_resp.keys == corrAns):
                        trial_resp.corr = 1
                    else:
                        trial_resp.corr = 0
                    # a response ends the routine
                    continueRoutine = False
            
            # check if all components have finished
            if not continueRoutine:  # a component has requested a forced-end of Routine
                break
            continueRoutine = False  # will revert to True if at least one component still running
            for thisComponent in TRIALComponents:
                if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                    continueRoutine = True
                    break  # at least one component has not yet finished
            
            # check for quit (the Esc key)
            if endExpNow or event.getKeys(keyList=["escape"]):
                core.quit()
            
            # refresh the screen
            if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
                win.flip()
        
        # -------Ending Routine "TRIAL"-------
        for thisComponent in TRIALComponents:
            if hasattr(thisComponent, "setAutoDraw"):
                thisComponent.setAutoDraw(False)
        # check responses
        if trial_resp.keys in ['', [], None]:  # No response was made
            trial_resp.keys=None
            # was no response the correct answer?!
            if str(corrAns).lower() == 'none':
               trial_resp.corr = 1  # correct non-response
            else:
               trial_resp.corr = 0  # failed to respond (incorrectly)
        # store data for trials (TrialHandler)
        trials.addData('trial_resp.keys',trial_resp.keys)
        trials.addData('trial_resp.corr', trial_resp.corr)
        if trial_resp.keys != None:  # we had a response
            trials.addData('trial_resp.rt', trial_resp.rt)
        
        # the Routine "TRIAL" was not non-slip safe, so reset the non-slip timer
        routineTimer.reset()

My idea was to extract the codes of the trigger column of the lists at the beginning of the TRIAL routine, and then eventually refer to it, but I wouldn’t know how to do that. Hope I was clear.

Thank you in advance!

The trigger variable is available to you automatically on each trial, just like your word variable.

Does this mean that if I do something like:

trigger = int(trigger)

and then call it when I need to set up the trigger code, this will ensure that for the program will send the right code for each of the words as defined in the csv files?

Yes. It may even already be an int, although it is always worth checking.

The way TrialHandlers work is that they step though each row in the conditions file, so values of each variable in each row are kept together.

If in doubt about values, just temporarily output the trigger variable to the screen as well to satisfy any concerns.

I didn’t know that. Thanks!

Thank for the advice! How can I do this?

In the same way you use the variable word to supply text for a stimulus on screen. Or you can just print the values to the console:

print(word)
print(trigger)

but remember to delete such statements from your code before running the actual experiment. It can be a good idea to minimise printing during an experiment for performance reasons.

Thank for all of your help, Michael! :slight_smile: