SightLab will automatically create a 'data' folder when you first run a session and save the following data by default. See below on how to add additional data to these files.
The files created are
Trial_Data file that reports tracking data and is created for every file individually.
Trial_Timeline_Dwell file that summarizes gaze events by time stamps.
Experiment_Summary file that includes events for the whole experiment, such as gaze events, time to first fixation, saccade averages, as well as custom measurements per trial.
Trial_Timeline_Fixation_Saccade (2.5 or higher) that summarizes information about each fixation and saccade
It is possible to customize the data included in these data files, in the GUI and in the scripts.
Trial Data
Trial_data shows a timestamp (from start of session and Unix Time Stamp) along with the trial Label, average frame rate, x,y,z coordinates of the gaze intersect (combined and individual eye), eye Euler (combined and individual eye), head position (6DOF), Fixation/Saccade status, saccade amplitude, velocity, average amplitude, peak velocity, pupil diameter (if you are using a headset that tracks pupil diameter), eye openness (if hardware allows), grab/release events, and custom flags as well as user added data. The default data collection is tied to the headset update rate (i.e. 90hz for a 90hz headset), but as of SightLab 2.5.5 you can change it to be on a timer by setting the flag for update rate using sightlab = sl.SightLab(updateRate = time in milliseconds)
Experiment Summary
Experiment Summary - Shows a summary of the Dwell view count, fixation count, dwell time, average view time, per trial saccade calculations, time to first fixation, trial length, as well as any additional data that you want to summarize per trial. See documentation on how to add more data.
Trial Timeline Dwell
Trial Timeline Dwell - Shows a timeline of when objects were viewed, for how long, and how many fixations there were per object. You can also add custom flags to the timeline file.
Trial Timeline Fixation Saccade
Trial Timeline Fixation Saccade - (2.5 or higher) shows a timeline of fixations and saccades, fixation/saccade length, average fixation dispersion angle and average saccade velocity, as well as delta angles and velocity.
SightLab Config
SightLab_Config .stlb files - STLB files are saved in a folder called "sightlab_configs" and are .json files that can be opened in a text editor or any method you use to open .json files if you need to access the data stored on them.
Config.json
config.json - This json file gives an overview of the options used for the session
Adding to the Data Files
See the Example folder "Custom Data Saving" in the ExampleScripts folder for some examples
#Saving trial datadefupdate_right_hand():rHandPos=sightlab.getAvatarRHand().getPosition()rHandPos=[round(x,3)forxinrHandPos]sightlab.setCustomTrialData(str(rHandPos[0]),'Rhand X')update_action=vizact.onupdate(0,update_right_hand)#Adding to the experiment summary file #(make sure this is done before sightlab.endTrial())sightlab.setExperimentSummaryData('condition',condition)#Adding to the experiment summary file second waytargetCorrect='Unknown'sightlab.customExperimentDataColumns={'Performance':targetCorrect}#wait for event to trigger changetargetCorrect='Correct'Addingtothetrialtimeline#Saving a flag to the timelinedefbuttonTrigger():sightlab.addToTimeline("t pressed")print("T key pressed")vizact.onkeydown('t',buttonTrigger)
Saving 6DOF of hand
def update_right_hand():
defupdate_right_hand():# Get right hand orientation (yaw, pitch, roll)rHandRot=sightlab.getAvatarRHand().getEuler()rHandRot=[round(x,3)forxinrHandRot]# Save position datasightlab.setCustomTrialData(str(rHandPos[0]),'Rhand X')sightlab.setCustomTrialData(str(rHandPos[1]),'Rhand Y')sightlab.setCustomTrialData(str(rHandPos[2]),'Rhand Z')# Save rotation datasightlab.setCustomTrialData(str(rHandRot[0]),'Rhand Yaw')sightlab.setCustomTrialData(str(rHandRot[1]),'Rhand Pitch')sightlab.setCustomTrialData(str(rHandRot[2]),'Rhand Roll')# Run the update function every frameupdate_action=vizact.onupdate(0,update_right_hand)
Example Usage
importsightlab_utils.sightlabasslfromsightlab_utils.settingsimport*sightlab=sl.SightLab(gui=False,pid=False)# Set up environmentenv=vizfx.addChild("sightlab_resources/environments/dojo.osgb")sightlab.setEnvironment(env)# Configure trialssightlab.setTrialCount(3)basketball=env.getChild('basketball')sightlab.addSceneObject('basketball',basketball,gaze=True,grab=True)sightlab.addTrackingTrialDataColumn("basketball",basketball)sightlab.addCustomTrialDataColumn("Condition")defsightLabExperiment():foriinrange(sightlab.getTrialCount()):yieldviztask.waitKeyDown(' ')# Start recording right hand positiondefupdate_right_hand():rHandPos=sightlab.getAvatarRHand().getPosition()rHandPos=[round(x,3)forxinrHandPos]sightlab.setCustomTrialData(str(rHandPos[0]),'Rhand X')sightlab.setCustomTrialData(str(rHandPos[1]),'Rhand Y')sightlab.setCustomTrialData(str(rHandPos[2]),'Rhand Z')update_action=vizact.onupdate(0,update_right_hand)# Start trialyieldsightlab.startTrial()# Define a button trigger eventdefbuttonTrigger():sightlab.setCustomTrialData('T key pressed','custom flag')print("T key pressed")vizact.onkeydown('t',buttonTrigger)# Set conditioncondition='condition1'sightlab.setCustomTrialData(condition,'Condition')sightlab.setExperimentSummaryData('condition',condition)yieldviztask.waitKeyDown(' ')yieldsightlab.endTrial(endExperimentText='Done')viztask.schedule(sightlab.runExperiment)viztask.schedule(sightLabExperiment)
Setting multiple objects to Experiment Summary
# Create a dictionary with all the dataexperimentData={'Feeling':chosen_rating1,'Rating':chosen_rating2}# Iterate through the dictionary and set each itemforcolumnName,datainexperimentData.items():sightlab.setExperimentSummaryData(columnName,data)#Alternative Optionsightlab.customExperimentDataColumns=experimentData
Note if data not saving, make sure you are not adding an end trial event (such as keypress) in both the GUI and in the code, as that may cause issues (i.e. if using a yield event to end the trial in the code, set the GUI to be "None" for event to end the trial).
Setting a Condition
yieldsightlab.startTrial(trialLabel="A")
Logging Flags or Events
To log specific events or flags during the experiment, such as a button press or a significant event:
sightlab.setDataDirectory()#Changes the name of the folder where the data is storedsightlab(directory=('absolute path to the current running script')
Starting and Stopping the Logger
importsightlab_utils.sightlabasslfromsightlab_utils.settingsimport*sightlab=sl.SightLab(gui=False,trackingdatalogging=False,replaydatalogging=False,timelinelogging=False,experimentdatalogging=False,fixationlogging=False)# Example showing how to set environment. Note that environment should be defined before #objects of interestenv=vizfx.addChild("sightlab_resources/environments/dojo.osgb")sightlab.setEnvironment(env)# set number of trialssightlab.setTrialCount(5)# add objects of interestsoccerball=env.getChild("soccerball")basketball=env.getChild("basketball")sightlab.addSceneObject("soccerball",soccerball,gaze=True,grab=True)sightlab.addSceneObject("basketball",basketball,gaze=True,grab=True)defsightLabExperiment():yieldviztask.waitKeyDown(" ")whileTrue:# Length of each trialyieldsightlab.startTrial(trialLength=3,startTrialText="start trial")ifsightlab.getTrialNumber()>=2:yieldsightlab.startTrial(trialLength=3,trackingDataLogging=True,replayDataLogging=True,experimentSummaryLogging=True,timeLineLogging=True,)else:yieldsightlab.startTrial(trialLength=3)yieldviztask.waitEvent(TRIAL_END)# Length of cooldown between trialsyieldviztask.waitTime(2)viztask.schedule(sightlab.runExperiment)viztask.schedule(sightLabExperiment)
Real time (within trial)
.setDataLoggingState
Example
sightlab.setDataLoggingState(0)# This will set it to stop
To start logging data (note this is camelCase, so trackingDataLogging instead of trackingdatalogging, as in the class)
To get access to the location of the data folder per trial you can use code such as this. This is the folder for each specific trial.
#Prior to SightLab 2.5fileName='{d}_{p.id}_experiment_data._trial_{t}.pdf'.format(d=sightlab.dateTime,p=sightlab.participantData,t=sightlab.trialNumber-1)#After 2.5fileName='{d}_{p}_experiment_data._trial_{t}.pdf'.format(d=sightlab.dateTime,p=sightlab.participantData[ID],t=sightlab.trialNumber-1)fullPath=os.path.join(sightlab.getExperimentDataFolderPath(),fileName)
Adding a Value to the Names of the Data Folder and Files
importsightlab_utils.sightlab_configasconfigconfig.DEFAULT_EXPERIMENT_DIRECTORY="{date}_{p}_TEST_CONDITION_experiment"# Set custom file nameconfig.EXPERIMENT_SUMMARY_FILE="{date}_{p}_TEST_CONDITION_experiment_summary.csv"importsightlab_utils.sightlabasslfromsightlab_utils.settingsimport*importsightlab_utils.sightlabasslfromsightlab_utils.settingsimport*