R.Muralikrishnan, MPI for Empirical Aesthetics. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Licence. ############################################################################## ## ## ## Milano Session 1 : Auditory ERP Study with Learning and Test Phases ## ## Experiment Script for use with Presentation ## ## Author: R. Muralikrishnan ## ## ## ############################################################################## ############################################################################## # Scenario Description Language (SDL) Header Part ############################################################################## # These button codes have to correspond to those set in 'Settings -> Response' active_buttons = 3; # There are 3 active buttons defined in 'Settings -> Response' button_codes = 1,2,3; # These are the codes of those buttons response_matching = simple_matching; # Enables features not in legacy_matching # Only those button presses that one expects are logged; not all response_logging = log_active; # Needed for EEG Trigger files write_codes = true; pulse_width = 5; default_output_port = 1; # This is most probably going to be the same for everyone. # This is the LPT Parallel port that you will define in the Port settings tab of # Presentation. This will be used as the output port for sending codes to EEG. # Defining this here saves getting a port number in the PCL part from the output_manager # and calling send_code etc. Stimulus events themselves will send these for us, provided we # define the correct port_codes in each Stimulus event. # Default Settings for Font, FG and BG Colours etc. default_background_color = "0, 0, 0"; # RGB codes in decimal; 000 => Black default_font = "Verdana"; default_font_size = 32; default_text_color = "000, 102, 153";#"000, 102, 153"; #"100, 64, 28"; # # An off-bluish foreground default_text_align = align_center; #"188, 145, 112"; #006699 #"000, 102, 153"; #9CBDDE #"156, 189, 222"; #E8F0F7 #"232, 240, 247"; #93A070 #"147, 160, 112"; default_deltat = 0; default_picture_duration = next_picture; /* This implies that all pictures ... /...are shown until the next picture is shown, unless otherwise specified */ #default_all_responses = false; ############################################################################## # Scenario Description Language (SDL) Part ############################################################################## begin; # ============================ # SDL Variable Declarations: - # ============================ # # We don't use any variables. All the timer parameters appear as numbers. # ============================== # Picture Stimuli Definitions: - Everything that is shown, including text! # ============================== # Screen definition for the trial that starts an Experimental Session. # Used as the first screen that the participant sees. Operator Controlled. line_graphic { coordinates = -400, -72, -400, 71; coordinates = 400, -72, 400, 71; coordinates = -400, -70, 400, -70; coordinates = -400, 70, 400, 70; line_width = 4; line_color = 32, 32, 32; } Lin_Border; picture { # text { caption = "Welcome! The Experiment will begin shortly."; }; text { caption = "Gleich geht's los."; }; # text { caption = "ஆய்வு சில நொடிகளில் ஆரம்பம்."; }; x = 0; y = 0; line_graphic Lin_Border; x = 0; y = 0; } P_Start_Exp; # Screen definition for the Pause trial # Operator Controlled! picture { # text { caption = "Let us continue after a short break!"; }; text { caption = "Weiter nach einer kurzen Pause!"; }; # text { caption = "ஒரு சிறிய இடைவேளைக்குப் பிறகு \n ஆய்வு தொடரும்."; }; x = 0; y = 0; line_graphic Lin_Border; x = 0; y = 0; } P_Pause; # Screen definition for the Continue trial # Participant Controlled! picture { # text { caption = "Please press a key to continue."; }; text { caption = "Zum Weitermachen \n Enter / Probanden Taste drücken.";}; # text { caption = "தொடர ஏதேனும் ஒரு பொத்தானை அழுத்தவும்.";}; x = 0; y = 0; line_graphic Lin_Border; x = 0; y = 0; } P_Continue; # Screen definition for the Interruption trial # Operator Controlled! picture { text { caption = "Sorry for the interruption. Please wait."; }; # text { caption = "¾¼í¸ÖìÌ ÅÕóи¢§È¡õ. \n º¢Ä ¦¿¡Ê¸Ç¢ø ¬ö× ¦¾¡¼Õõ."; }; x = 0; y = 0; line_graphic Lin_Border; x = 0; y = 0; } P_Interruption; # Screen definition for showing the focus star picture { bitmap { filename = "Focus_Star_new1.bmp"; }; # Use Focus_Star_new1.bmp x = 0; y = 0; } P_Focus_Star; # Screen definition for showing the focus smiley picture { bitmap { filename = "Focus_Smiley.jpg"; } Bmp_Focus_Smiley; x = 0; y = 0; } P_Focus_Smiley; # Screen definition for showing the Picture Card picture { # box { width = 900; height = 360; color = "255, 255, 255"; }; # Draw a white box of the specified width and height. # x = 0; # y = 0; bitmap { filename = "Correct-Incorrect-Qsmall-L.jpg"; }; # Show Correct-Incorrect-Q.jpg to test comprehension. x = 0; y = 0; } P_Test_Comprehension; # Screen definition for showing the Feedback picture { bitmap { filename = ""; preload = false; } Bmp_Feedback; # PCL Program below fills the file name x = 0; y = 0; # text { caption = " "; max_text_width = 950;} Txt_Feedback; # PCL Program below fills the caption. Used for providing Accuracy feedback for the experimenter. # max_text_width works from Presentation version 16.4 or above. #x = 0; #y = 270; } P_Feedback; # Screen definition for the End_Thanks trial picture { # text {caption = "We're done! Thank you very much!";}; # text {caption = "¬ö× þòмý ¿¢¨È× ¦ÀüÈÐ. Á¢ì¸ ¿ýÈ¢.";}; text {caption = "Danke...das war's!";}; x = 0; y = -180; line_graphic Lin_Border; x = 0; y = -180; bitmap { filename = "Smiley-Thumbs-Up.jpg"; preload = true;}; x = 0; y = 90; } P_End_Thanks; # Screen definition for playing a video stimulus video { filename = "Video4.mpg"; # PCL Program below changes the file name if necessary release_on_stop = false; # Ensures that the video is not released from memory when stopped. Useful for playing x-second chunks of the video # ...the next time the trial is called, the video starts where it stopped. start_time = 500; # The first time, the video starts not at the beginning, but from the frame at 500 ms. } Vid_Video_Stimulus; ##### #### Specific for presenting Auditory Stimuli ------------------------------- # ============================ # Sound Stimuli Definitions: - # ============================ sound { wavefile { filename = ""; # PCL Program below fills the file name preload = false; } Wav_Auditory_Stimulus; } S_Auditory_Stimulus; #### #===================== # Trial Definitions: - #===================== /**** / Note that the name 'Trial' could be misleading. Unless otherwise specified, / what we mean by a 'Trial' here is actually a sub-trial or sub-task that is / part - and thereby defines the structure - of an actual experimental trial. ****/ /**** / Template for defining an SDL Trial. / trial / { / Trial-related parameters such as trial_duration, trial_type etc. / Trial-related parameters / / Stimulus event 1 such as picture, sound, video, nothing or force-FB; / Stimulus event parameters such as time, event code etc. / If the parameters aren't specified, the default values are used!!! / / Stimulus event 2; / its parameters...and so on / } ****/ trial { trial_duration = 1000; #1500 all_responses = false; stimulus_event { picture {}; # This is the default picture, which is nothing! code = "CLS"; # Comment this out to avoid seeing this in the logfile. }; } T_Blank_Screen; # Definition of the Trial to start an Experimental Session. # Operator Controlled! trial { trial_duration = forever; # Keep running the trial... trial_type = specific_response; # ...until the following specific response. terminator_button = 3; # Operator PC - ENTER key. stimulus_event { picture P_Start_Exp; # Show P_Start_Exp. code = "The Experiment starts now!"; }; } T_Start_Exp; # Definition of the Trial to continue further. # Participant Controlled! trial { trial_duration = forever; # Keep running the trial... trial_type = first_response; # ...some key press (Operator / Participant) stimulus_event { picture P_Continue; # Show P_Continue. code = "Trials follow!"; }; } T_Continue; # Definition of the Trial to Launch an Experimental Trial trial { trial_duration = 500; # Run the trial for 500 ms... all_responses = false; # ..without recognising any key presses. stimulus_event { picture P_Focus_Smiley;#P_Focus_Star; # Show the focus star for fixation. code = ""; # Code set below in the PCL program. # port_code = ; # Port code set by the PCL program. } E_Launch_New_Trial; } T_Launch_New_Trial; # Definition of the Trial to keep showing a Focus Star/Smiley (or whatever else) for fixation. trial { trial_duration = 500; # Show smiley until the next clear-screen... all_responses = false; # ..without recognising any key presses. stimulus_event { picture P_Focus_Smiley; # Show the focus smiley for fixation. code = "*"; # Comment this out later to avoid seeing this in the log file. }; } T_Keep_Showing_Smiley; #### Specific for presenting Auditory Stimuli ------------------------------- # Definition of the Trial to play the Auditory Stimulus trial { trial_duration = stimuli_length; # But we're modifying this in the PCL such that the duration is stimuli_length + 500 ms, which we can't do here; See below. all_responses = false; #monitor_sounds = true; (default). # If false, then, any sound that was/has started playing when prior to/during this trial # would continue to be played even if this trial ends. # Manipulated in PCL program below; We don't do it here # because the default behaviour is what we want normally; # Only in special circumstances do we want to change that # behaviour. stimulus_event { sound S_Auditory_Stimulus; code = ""; # PCL Program sets Event code # port_code = ; # PCL Program sets port code } E_Auditory_Stimulus; } T_Auditory_Stimulus; #### # Definition of the Trial to show the Picture Card for the Comprehension Task trial { trial_duration = 7000; # Show the comprehension trial for a maximum of 7 seconds. trial_type = specific_response; terminator_button = 1,2; # The exact response can be either of these; stimulus_event { picture P_Test_Comprehension; code = "195"; # PCL Program sets this. port_code = 195; # Send '195' to EEG # target_button = 1,2; # PCL Program sets this. } E_Test_Comprehension; } T_Test_Comprehension; # Definition of the Trial to provide a feedback to the participant / experimenter. trial { trial_duration = forever; # PCL Program below changes this trial_type = first_response; # Any key press ends the trial; PCL Program below changes this monitor_sounds = false; #(default true). # If false, then, any sound that was/has started playing when prior to/during this trial # would continue to be played even if this trial ends. # Manipulated in PCL program below. stimulus_event { picture P_Feedback; # Show the feedback picture. code = ""; # Code set below in the PCL program. } E_Feedback; } T_Feedback; # Definition of the Trail to present a video stimulus trial { trial_duration = 15000 ; # Play 15-second chunks. # We could modify this in the PCL such that the duration is stimuli_length + 500 ms, which we can't do here; See below. all_responses = false; monitor_sounds = false; #(default true). # If false, then, any sound that was/has started playing when prior to/during this trial # would continue to be played even if this trial ends. # Manipulated in PCL program below. stimulus_event { video Vid_Video_Stimulus; code = "Video"; port_code = 99; } E_Video_Stimulus; } T_Video_Stimulus; # Definition of the Trial to send a code indicating that a Timeout has occurred. /* When a button-pressed response occurs, 1 or 2 is sent to EEG depending upon the button pressed. When a timeout occurs, nothing gets sent. Just in order to have equal number of lines in the trigger files later, it's better to send a code indicating timeout. (Yes, IN ADDITION to the usual code 199 that will follow.) */ trial { trial_duration = 10; all_responses = false; stimulus_event { nothing {}; # This is the default picture, which is nothing! code = "Timeout"; port_code = 3; } E_Report_Timeout_to_EEG; } T_Report_Timeout_to_EEG; # Definition of the Trial to send the response code to EEG trial { trial_duration = 20; all_responses = false; stimulus_event { nothing {}; # Basically, nothing is done! time = 15; /* Start this event 15 seconds after the trial starts. This is to provide a delay in sending the code to EEG to avoid trying to reach the port when it is still busy having just received the response 1 or 2 from the button box, or the timeout code. */ # code = "Send Code"; # Comment this out to avoid seeing this in the logfile. # port_code = 196, 197 or 199, PCL Program fills this!!! } E_Response_Code_to_EEG; } T_Response_Code_to_EEG; # Definition of the Trial to show a Pause # Operator Controlled trial { trial_duration = forever; trial_type = specific_response; terminator_button = 3; stimulus_event { picture P_Pause; code = "Pause"; }; } T_Pause; # Definition of the Trial to Interrupt in the middle of a session # Operator Controlled trial { trial_duration = forever; trial_type = specific_response; terminator_button = 3; stimulus_event { picture P_Interruption; code = "Interrupted!!!"; }; } T_Interruption; # Definition of the Trial to end the session # Operator Controlled trial { trial_duration = forever; all_responses = false; trial_type = first_response; stimulus_event { picture P_End_Thanks; code = "End of Session!"; }; picture P_End_Thanks; } T_End_Thanks; ############################################################################## # Presentation Control Language (PCL) Program Part ############################################################################## begin_pcl; preset string V_Version; # Prompt the version at the beginning!!! int N_of_Trials = 320; # Number of Experimental Trials per Session. int N_of_Blocks = 4; # Number of Blocks per Session. int N_of_Trials_per_Block = N_of_Trials/N_of_Blocks; # Number of Experimental Trials per Block. # MILANO SESSION 1: Each block has 80 Trials totally, of which # ...four-fifths (64) are Learn trials; # ...one-fifth (16) are Test trials; int N_of_Learn_Trials = (N_of_Trials_per_Block/5)*4; # Four-fifths of a block. input_file F_Session_List = new input_file; F_Session_List.open("Session_List_" + V_Version + "_Session1.txt"); # This is the file containing the list of stimuli for one session. # Each line in this file must correspond to one experimental trial. #### # Columns of strings in the order found in the input Session List file. string V_Auditory_Stimulus; string V_Item; string V_Condition; string V_Condition_Code; string V_Trial_Type; string V_Expected_Response; int V_Correct_Answers = 0; # output_port O_Port_to_EEG = output_port_manager.get_port(1); stimulus_data D_Stimulus_Data = stimulus_manager.last_stimulus_data(); #======================== # Main Experiment Loop: - #======================== loop /*** Begin Main Loop 1 for Blocks ***/ int V_Current_Block = 1 until V_Current_Block > N_of_Blocks begin if V_Current_Block == 1 then T_Start_Exp.present(); # Present an Introduction to the Experiment Bmp_Feedback.set_filename("Adventurer.jpg"); Bmp_Feedback.load(); T_Feedback.present(); Bmp_Feedback.set_filename("WorldMap10.jpg"); Bmp_Feedback.load(); T_Feedback.present(); else T_Pause.present(); end; T_Continue.present(); T_Blank_Screen.present(); # For Session 1, this will be the beginning of the Learning Trials # Just play a simple message to that effect Bmp_Feedback.set_filename("Adventurer.jpg"); Bmp_Feedback.load(); T_Feedback.set_all_responses(false); T_Feedback.set_duration(1000); T_Feedback.present(); # Play a message signalling the forthcoming trials Wav_Auditory_Stimulus.set_filename("Los-gehts.wav"); Wav_Auditory_Stimulus.load(); E_Auditory_Stimulus.set_port_code(99); E_Auditory_Stimulus.set_event_code("Los-gehts.wav"); T_Auditory_Stimulus.present(); T_Blank_Screen.present(); Wav_Auditory_Stimulus.unload(); T_Blank_Screen.present(); #========== # Loop 2: - #========== loop /*** Begin Loop 2 for Trials ***/ int V_Current_Trial = 1 until V_Current_Trial > N_of_Trials_per_Block begin V_Auditory_Stimulus = F_Session_List.get_string(); # Eg: 01SAI V_Item = F_Session_List.get_string(); # Eg: 01 V_Condition = F_Session_List.get_string(); # Eg: SAI V_Condition_Code = F_Session_List.get_string(); # Eg: 230 V_Trial_Type = F_Session_List.get_string(); # Eg: LEARN/TESTx Trial V_Expected_Response = F_Session_List.get_string(); # Eg: 2 (Right button = Correct) # Do filename and event-code assignments valid during this exp-trial; # Load wavefile and bitmap stimuli that are needed for this trial; /* We do this before launching the experimental trial so as to keep as minimal intereference as possible in trial timings. You see, these things consume processor time, however small they are! */ E_Launch_New_Trial.set_port_code(int(V_Item)); E_Launch_New_Trial.set_event_code("B" + string(V_Current_Block) + " T" + string(V_Current_Trial)); #### Specific for presenting Auditory Stimuli ------------------------------- Wav_Auditory_Stimulus.set_filename(V_Auditory_Stimulus + ".wav"); Wav_Auditory_Stimulus.load(); # Get the duration of the loaded wavefile, and set the duration of the Trial that will present it such that # the trial continues to run for 500 ms after the audio ends. # Wav_x.duration() returns the duration of the wavefile in milliseconds as an int; (Unlike videos, for which the duration is returned as a double). T_Auditory_Stimulus.set_duration(Wav_Auditory_Stimulus.duration() + 500); E_Auditory_Stimulus.set_port_code(int(V_Condition_Code)); # Set Condition Code for sending to EEG E_Auditory_Stimulus.set_event_code(V_Auditory_Stimulus + ".wav"); #### #### Specific for presenting Video Stimuli ------------------------------- # Vid_Video_Stimulus.prepare(); # This is done so the frames are queued in memory; If it is not done manually, Presentation will # do it automatically when the trial containing the Vid_x stimulus is presented; # Doing this here clashes with release_on_stop=false setting. # Get the duration of the prepared video file, and set the duration of the Trial that will present it such that # the trial continues to run for 500 ms after the video ends. # Vid_x.duration() returns the duration of the video in milliseconds as a double; (Unlike wavefiles, for which the duration is returned as an int). # T_Video_Stimulus.set_duration(int(Vid_Video_Stimulus.duration()) + 500); #### E_Test_Comprehension.set_target_button(int(V_Expected_Response)); # Dirty hard-coded solution for the 08-09 Presentation Bug!!! if V_Item == "08" then V_Item = "8"; elseif V_Item == "09" then V_Item = "9"; end; # Execute the Experimental Trial!!! T_Launch_New_Trial.present(); # Show Star for 500 ms /************ Auditory Stimulus Presentation Begins *****************/ #T_Keep_Showing_Smiley.present(); T_Auditory_Stimulus.present(); /************ Auditory Stimulus Presentation Ends *******************/ T_Blank_Screen.set_duration(100); T_Blank_Screen.present(); T_Blank_Screen.set_duration(1000); /************ Comprehension Judgement Task Begins *****************/ # If the trail type is 'TESTx', then # present the trial to test whether a violation is judged as such correctly or not, # and monitor the response. This is not applicable for 'LEARN' trials. if V_Trial_Type != "LEARN" then T_Test_Comprehension.present(); # Monitor the Response and send appropriate port codes to EEG!!! D_Stimulus_Data = stimulus_manager.last_stimulus_data(); # To delay sending the following codes to the Output Port!!! # Because these are almost at the same time as the Response there, so the port # cannot handle it unless there's a short delay. if (D_Stimulus_Data.type() == stimulus_hit) then E_Response_Code_to_EEG.set_port_code(196); E_Response_Code_to_EEG.set_event_code("Correct"); T_Response_Code_to_EEG.present(); V_Correct_Answers = V_Correct_Answers + 1; elseif (D_Stimulus_Data.type() == stimulus_incorrect) then E_Response_Code_to_EEG.set_port_code(197); E_Response_Code_to_EEG.set_event_code("Incorrect"); T_Response_Code_to_EEG.present(); elseif (D_Stimulus_Data.type() == stimulus_miss) then T_Report_Timeout_to_EEG.present(); E_Response_Code_to_EEG.set_port_code(199); E_Response_Code_to_EEG.set_event_code("Timeout"); T_Response_Code_to_EEG.present(); end; end; /************ Comprehension Judgement Task End ********************/ T_Blank_Screen.present(); #### Specific for presenting Auditory Stimuli ------------------------------- # Unload all memory occupiers such as wavefile stimuli. Wav_Auditory_Stimulus.unload(); T_Auditory_Stimulus.set_duration(stimuli_length); #### if (V_Current_Trial == N_of_Learn_Trials) then # End of Learn Trials. # Test Trials follow. # Play a message signalling the forthcoming test trials Wav_Auditory_Stimulus.set_filename("TestTrialsFollow1" + string(V_Current_Block) + ".wav"); Wav_Auditory_Stimulus.load(); T_Auditory_Stimulus.set_monitor_sounds(false); # => End the trial immediately after the sound starts playing, # go to the next step, but keep playing sound to its duration even after trial ends. E_Auditory_Stimulus.set_port_code(99); E_Auditory_Stimulus.set_event_code("TestTrialsFollow1" + string(V_Current_Block) + ".wav"); T_Auditory_Stimulus.present(); # Show the picture of the adventurer Bmp_Feedback.set_filename("Adventurer.jpg"); Bmp_Feedback.load(); T_Feedback.set_duration(10500); #10.5 seconds T_Feedback.present(); # Play a filler-video showing the train video T_Video_Stimulus.present(); # Since we've set release_on_stop = false, every time this is called, # the next 15 seconds from the video is played. # We've set the monitor_sounds to false, which means any sounds playing won't be interrupted. T_Feedback.present(); # Show the Correct-Incorrect picture when explaining the forthcoming task Bmp_Feedback.set_filename("Correct-Incorrect-Qsmall-L.jpg"); Bmp_Feedback.load(); T_Feedback.set_duration(25000); #25 seconds T_Feedback.present(); T_Blank_Screen.present(); T_Blank_Screen.present(); # Reset things Bmp_Feedback.unload(); Wav_Auditory_Stimulus.unload(); T_Auditory_Stimulus.set_monitor_sounds(true); #(Restore default behaviour: Trial ends -> Sound ends as well) T_Feedback.set_duration(2000); end; # Go to the Next Trial V_Current_Trial = V_Current_Trial + 1; #=========== # End Loop 2 #=========== end; /*** End Loop 2 for Trials ***/ # At the end of a block, the last part of which would have been Test Trials, # display the updated world map as a feedback about the progress of the adventurer. # Play a sound that would match with the animation below Wav_Auditory_Stimulus.set_filename("Sound735.wav"); Wav_Auditory_Stimulus.load(); E_Auditory_Stimulus.set_port_code(99); E_Auditory_Stimulus.set_event_code("Sound735.wav"); T_Auditory_Stimulus.set_monitor_sounds(false); # => End the trial immediately after the sound starts playing, # go to the next step, but keep playing sound to its duration even after trial ends. T_Auditory_Stimulus.present(); # Do a little animation using the set_load_size method for the bitmap Bmp_Feedback.set_filename("WorldMap1" + string(V_Current_Block - 1) +".jpg"); Bmp_Feedback.load(); T_Feedback.set_duration(20); loop int V_Counter = 30 until V_Counter < 1 begin # Progressively increase the size of the image from very small to full size double V_Scaling_Factor = 1.0/double(V_Counter); Bmp_Feedback.set_load_size(0.0, 0.0, V_Scaling_Factor); # Height and Width must be 0.0 (double) when scaling factor (double) is specified. Bmp_Feedback.load(); T_Feedback.present(); V_Counter = V_Counter - 1; end; # Play a sound that would match with the animation below Wav_Auditory_Stimulus.set_filename("Sound25.wav"); Wav_Auditory_Stimulus.load(); E_Auditory_Stimulus.set_port_code(99); E_Auditory_Stimulus.set_event_code("Sound25.wav"); T_Auditory_Stimulus.present(); # Do a little animation by interchanging the old and new images very quickly loop int V_Counter = 1 until V_Counter > 16 begin Bmp_Feedback.set_filename("WorldMap1" + string(V_Current_Block-1) +".jpg"); Bmp_Feedback.load(); T_Feedback.set_duration(30); T_Feedback.present(); Bmp_Feedback.set_filename("WorldMap1" + string(V_Current_Block) +".jpg"); Bmp_Feedback.load(); T_Feedback.set_duration(60); T_Feedback.present(); V_Counter = V_Counter + 1; end; T_Feedback.set_duration(2000); T_Feedback.present(); # Reset things Bmp_Feedback.unload(); Wav_Auditory_Stimulus.unload(); T_Auditory_Stimulus.set_monitor_sounds(true); #(Restore default behaviour: Trial ends -> Sound ends as well) # Go to the Next Block V_Current_Block = V_Current_Block + 1; #================ # End Main Loop 1 #================ end; /*** End Main Loop 1 for Blocks ***/ # Close all the open files F_Session_List.close(); # Finish off the session!!! T_End_Thanks.present();