SightLab  2.0 Code Attributes and Methods

importing SightLab

import sightlab_utils.sightlab as slfrom sightlab_utils.settings import * 

Creating and configuring a SightLab instance

sightlab = sightlab.SightLab()

sightlab = sightlab.SightLab(gui = False)


Class SightLab

    The SightLab class initializes an environment for visual experiments with configurable attributes for GUI elements, data logging, and screen recording settings.

    Attributes:

         gui (bool): If True, enables the graphical user interface.        pid (bool): Enable or disable the participant ID.        biopac (bool): If True, enables integration with Biopac systems.        timer (bool): If True, enables the timer to be running.        fadequad (bool): If True, enables the fade quad.        headlight (bool): If True, enables the headlight.        mouselock (bool): If True, locks the mouse cursor.        gazepathvisible (bool): If True, makes the gaze path visible at the end of a trial.        console (bool): If True, enables the console display.        screenrecord (bool): If True, enables recording of the screen.        gazepointvisible (bool): If True, makes gaze points visible on the mirrored view.        trackingdatalogging (bool): If True, logs tracking data.        replaydatalogging (bool): If True, logs replay data.        experimentdatalogging (bool): If True, logs experiment data.        timelinelogging (bool): If True, logs timeline data.        continuekey (bool): If True, enables the continue key (defined in settings, default spacebar).        trialcount (int or None): The number of trials, or None if unlimited.        configPath (str or None): Path to the configuration file, or None for default. repetitions: Set if you want to run blocks of trials or loop through a set of trials.  datafilesaving (PER_TRIAL): Choose whether to save data files PER_TRIAL or COMBINED        hardwareconfig(None): Specify hardware configuration, without having the choice dropdown (i.e. "Desktop"]        vizconnectconfig(None): Specify custom vizconnect or vizconnect list from a dictionary        vizconnectconfiglist(None): Specify what to show in hardware dropdown from built in options

Setting the Environment 

env = vizfx.addChild('sightlab_resources/environments/dojo2.osgb')

sightlab.setEnvironment(env)

Configures the environment settings for the experiment.

    def setEnvironment(env, trial='DEFAULT', mode='MODEL_3D', mediaType="video", mediaFormat="Stereoscopic T/B", headlightIntensity=0):
Parameters:      env: The environment object to be used.      trial (str): Trial type, default is 'DEFAULT'.      mode (str): The mode of the experiment, default is 'MODEL_3D', use 'MEDIA_360 for 360 media.      mediaType (str): Type of media used, default is 'video', option for 'image'.      mediaFormat (str): Format of the media, default is 'stereo'.      headlightIntensity (int): Intensity of the headlight, default is 0, set to "1" or "2" for headlight on.            

Setting Trial Count

sightlab.setTrialCount(1)


Adding Target Objects

sightlab.addSceneObject(name,sceneObject,gaze = True)

Note: If not a child of the environment, then SceneObjects must be added before scheduling sightlab in the code (i.e. before sightlab.startTrial())

Parameters:objectName (str):The name identifier for the scene object to be added.sceneObject:The scene object instance to be added to the scene.gaze (bool, optional, default: False):If True, the scene object will be added to the gaze interaction category. It enables gaze tracking for the object.grab (bool, optional, default: False):If True, the scene object will be added to the grab interaction category. It enables grabbing interactions for the object.visible (bool, optional, default: True):If False, the scene object will be made invisible. This involves setting the alpha value to viz.OFF and disabling shadow casting for the object.avatar (bool, optional, default: False):If True, the scene object is treated as an avatar and is added to the avatar objects category.

Grabbing Objects

 sightlabObject.addSceneObject("tablet", tablet, gaze = False, grab = True)


Adding Object Only for Tracking

sightlab.addSceneObject('ball', ball)


Multiple Objects

sceneDict = {'Soccerball': [True, True],'Baseball': [True, True],'Globe': [True, True]}for item in sceneDict: sightlab.addSceneObject(item, env.getChild(item), gaze = sceneDict[item][0], grab = sceneDict[item][1]) 

Starting Trials

Starting a trial in SightLab can be done using the start/end conditions in the GUI, keyboard events or programmatically within a script. Below are methods to initiate trials:

Using Keyboard Events:

To start a trial using the spacebar, you can set up a keyboard event:

vizact.onkeydown(' ', sightlab.startTrial)

This binds the spacebar to start the trial.

Programmatic Start:

To start a trial programmatically, use the following approach within a Vizard task:

yield viztask.waitKeyDown('s')  # Waits for the 's' key to be pressed

yield sightlab.startTrial(trialLength=60, trialLabel ="A", startTrialText="Beginning Trial", textContinueEvent='triggerPress')

This example waits for the 's' key and then starts the trial with specified parameters.

Method Signature:

startTrial(condition = = NO_CONDITION, trialLength=-1, trialLabel="A", startTrialText=None, startExperimentText=None, textContinueEvent='triggerPress', textContinueKey=None, trackingDataLogging=True, replayDataLogging=True)

Ending Trials

Ending a trial can be done via keyboard events, callbacks, or directly within a function.

Using Keyboard Events:

vizact.onkeydown('e', sightlab.endTrial)

Programmatic End: 

yield sightlab.endTrial()

Using Callbacks: 

viztask.schedule(sightlab.endTrial())

Schedules the trial to end based on specific events or conditions within your experiment flow.

Method Signature:

endTrial(endTrialText=None, endExperimentText=None)

Direct Event Trigger:

To directly send an event to end a trial from within a function: 

viz.sendEvent(INITIATE_TRIAL_END)

Use this method when you need to trigger the end of a trial based on specific logic or external conditions. 


Scheduling SightLab

 viztask.schedule(sightlab.runExperiment())


Setting Condition Based on Vizconnect being Used

if sightlab.getConfig() == "Meta Pro Body":


Changing Starting Position

SightLab (can also add a Starting Point object in the GUI (see Creating a New Scene)

sightlab.transportNode.setPosition([0,0,0])

#or can use this

sightlab.setStartPoint((2,0,0))

Session Replay Starting Point

replay.transportNode.setPosition([0,0,0])


Checking which object is being Targeted

if e.object == sightlab.sceneObjects[GAZE_OBJECTS][TARGET_PAINTING]:

Get Current Time

sightlab.hud.getCurrentTime()

Accessing the Environment Object

env = sightlab.getEnvironment()

Using the environment object in context

#Access after EXPERIMENT_START

def sightLabExperiment():

    global env

    yield viztask.waitEvent(EXPERIMENT_START)

    env = sightlab.getEnvironment()


#If need access to it before use env = None, and put inside a function that can be called after it is set in the trial

def initialize_environment():

        target = env.getChild(name)

def sightLabExperiment():

    global env

    yield viztask.waitEvent(EXPERIMENT_START)

    

    env = sightlab.getEnvironment()

    initialize_environment()

   

Changing Models to use for Avatar

head = vizfx.addChild(AVATAR_HEAD_RESOURCE_PATH+'/Male1.osgb'))sightlab.setAvatarHead(head)

Other way

sightlab.setAvatarHead(head = vizfx.addChild(AVATAR_HEAD_RESOURCE_PATH+'/Male1.osgb'))


#Setting Hands

sightlab.setAvatarRightHand(rightHand= vizfx.addChild(AVATAR_HANDS_RESOURCE_PATH+'/empty.osgb'))

Toggling Visibility of Overlays

sightlab.toggleHUD()

Settings

Many settings are now accessible via the sightlab object (see below). The settings file is now in the sightlab_utils folder. See the settings documentation page for more details

Adding to the Data Files


# Create a dictionary with all the data

experimentData = {

'Object Size': sceneObjectSizeString,

'NUM_OBJ': NUM_OBJ,

'Time to Find Target': time_to_find_target,

'Target Position': targetPos,

'Target Correct': targetCorrect,

'Confidence Level': sightlab.ratingChoice}

# Iterate through the dictionary and set each item

for columnName, data in experimentData.items():

    sightlab.setExperimentSummaryData(columnName, data)

    sightlab.customExperimentDataColumns = experimentData

Setting Condition

yield sightlab.startTrial(trialLabel = "A")

HeadLight On or Off

sightlab.setHeadLight(state, intensity = None, color = None)

Adding additional file to the Data folder

fileName = '{d}_{p.id}_experiment_data._trial_{t}.pdf'.format(d=sightlab.dateTime, p=sightlab.participantData, t=sightlab.trialNumber)

        fullPath = os.path.join(sightlab.getExperimentDataFolderPath(), fileName)

        drawChart(fullPath, sightlab.getPlotData())

Toggling on and off tracking per trial

import sightlab_utils.sightlab as slfrom sightlab_utils.settings import *
sightlab = sl.SightLab(gui = False,trackingdatalogging=False,replaydatalogging = False,timelinelogging= False, experimentdatalogging= 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)
def sightLabExperiment(): yield viztask.waitKeyDown(' ') while True: #Length of each trial yield sightlab.startTrial(trialLength=3, startTrialText= 'start trial') if sightlab.getTrialNumber() >=2: yield sightlab.startTrial(trialLength=3, trackingDataLogging = True, replayDataLogging = True, experimentSummaryLogging = True, timeLineLogging = True) else: yield sightlab.startTrial(trialLength=3) yield viztask.waitEvent(TRIAL_END) #Length of cooldown between trials yield viztask.waitTime(2)
viztask.schedule(sightlab.runExperiment)viztask.schedule(sightLabExperiment)

Session Replay

from sightlab_utils import replay as Replay

from sightlab_utils.replay_settings import *


replay = replay.SightLabReplay()

To change the name of a session replay you need to keep the end tag:

replay_data_1 tag

Set position

replay.transportNode.setPosition([x,y,z])

Accessing environment SessionReplay

env = replay.getEnvironmentObject()

Accessing Scene Objects

screen = replay.sceneObjects[GAZE_OBJECTS]['screen']

Getting Trial Number

trial_number = int(replay.currTrial)

Getting Gaze Point

gazePointObject = replay.sceneObjects[GAZE_POINT_OBJECT]['1']

Additional Functionality Changes

Rating Scale

yield sightlab.showRatings('how are you feeling?',ratingScale= scaleList, pauseTimer = True)

scaleList can be anything now (i.e. "A", "B", "C" or "Yes", "No")

sightlab.ratingChoice #Get a handle to the rating that is chosen

Can also add a start or end rating scale (see startTrial and endTrial)

Instructions

yield sightlab.showInstructions('test')

yield viztask.waitEvent('triggerPress')

yield sightlab.hideInstructions()


Gaze Based Interactions

def gazeActionEnd(e):

    if e.object == sightlab.sceneObjects[GAZE_OBJECTS]['target_objecct']:

        print('item found')

        viz.sendEvent(INITIATE_TRIAL_END)

vizact.addCallback(sightlab.GAZE_TIME_EVENT, findItem)


Adjusting Fixations/Saccade Parameters

Note: these need to be set after .startTrial()

sightlab.setDwellTimeThreshold(dwellTime = DWELL_THRESHOLD)      

sightlab.setFixationSaccadeThresholds(dispersionThreshold = 1, durationThreshold = 0.1)

Reset Position

viz.callback(viz.getEventID('ResetPosition'), sightlab.resetViewPoint)

This will reset your position back to the origin relative to your physical location. To change this point to a different value, will need to manually add the resetPosition code. 

Change Default Folder

sightlab.setEnvironmentDirectory('path_to_resources_folder')

Set Starting Text

sightlab.setStartText('press Spacebar to start')

Run a Loop per trial

for i in range(sightlab.getTrialCount()):

Scene Objects

ENVIRONMENT_OBJECT: vizfx.addChild(DEFAULT_ENVIRONMENT_PATH),

AVATAR_HEAD_OBJECT: vizfx.addChild(DEFAULT_AVATAR_HEAD_PATH),

AVATAR_RIGHT_HAND_OBJECT: vizfx.addChild(DEFAULT_AVATAR_RIGHT_HAND_PATH),

AVATAR_LEFT_HAND_OBJECT: vizfx.addChild(DEFAULT_AVATAR_LEFT_HAND_PATH),

GAZE_POINT_OBJECT: vizfx.addChild(DEFAULT_GAZE_POINT_PATH),

                

GAZE_OBJECTS: {},

GRAB_OBJECTS: {},

INVISIBLE_OBJECTS: {},

                

CUSTOM_OBJECTS: {},

AVATAR_OBJECTS: {}

Regions to not be visible

sightlab.addSceneObject("wall2", wall2, gaze = True, visible = False)

Getting Access to Eye Tracker

sightlab.getEyeTracker()

Getting Access to Regions of Interest for 360 Media

region1 = sightlab.getRegionOfInterest('tire')

Setting the STIM File Path

# Initialize StimReader with the STIM file

SR = stim_reader.StimReader(STIM_FILE_LOCATION)

SR.fillStimFileEntryList()

Additional Changes and Notes

TRIAL_END_EVENT is now TRIAL_END

VIZCONNECT_CONFIGS is now VIZCONNECT_CONFIG

ENVIRONMENT is a constant already used, use "ENVIRONMENT_MODEL" instead

Getting Position of Child Objects

If you are using env.getChild to access your objects you need to use a .getTransform to access the object's position:


targetTransform = env.getTransform('targetTransform')


It also works to call the getChild command on the GEODE associated with the object


Set Maximum Distance for intersection of Gaze Point

sightlab.setMaxDistance(1000) 

Getting 360 Media Sphere and Video File

sightlab.getMediaFile()

sightlab.getMediaObject()

For more information on the additional modules and code available with Vizard see the Vizard Documentation. Or  the Vizard Command Index