From c9c22de47f46407bfda1518f8913bb319595b768 Mon Sep 17 00:00:00 2001 From: tristanyates Date: Tue, 3 Feb 2026 12:56:21 -0500 Subject: [PATCH] init cartoonlive --- Scripts/Experiment_CartoonLive.m | 157 ++++++++++++++++++++++++++ Scripts/GenerateTrials_CartoonLive.m | 161 +++++++++++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100755 Scripts/Experiment_CartoonLive.m create mode 100755 Scripts/GenerateTrials_CartoonLive.m diff --git a/Scripts/Experiment_CartoonLive.m b/Scripts/Experiment_CartoonLive.m new file mode 100755 index 0000000..481c054 --- /dev/null +++ b/Scripts/Experiment_CartoonLive.m @@ -0,0 +1,157 @@ +%% Show a movie. +% +% Opens a movie to be played to the infant to capture attention. +% The movie will end if there is a key press. However, the volume buttons +% can still be used and the left and right arrow keys can be used to +% rewind/fastforward +% +% +%TY 01/26/2021 (identical to Experiment_Child_Play) + +function Data=Experiment_CartoonLive(varargin) + +%Set variables +ChosenBlock=varargin{1}; +Window=varargin{2}; +Conditions=varargin{3}; + +% Decide whether you are waiting for TR based on whether you are connected +% to the scanner +VideoStruct.WaitforTR=Window.isfMRI; + +%Is the rect value a proportion of the screen or in pixels? +if all(Conditions.Parameters.Rect<1) + + RectValues([1,3])=Conditions.Parameters.Rect([1,3]).*Window.Rect(3); + RectValues([2,4])=Conditions.Parameters.Rect([2,4]).*Window.Rect(4); + +else %If pixels then just use that value + + RectValues=Conditions.Parameters.Rect; +end + +VideoStruct.MovieRect= RectValues; + +%Set no timing constraints +TimingStruct.Preload=Conditions.Parameters.Preload; +TimingStruct.PlannedOnset=0; + +%Set the input constraints +InputStruct.isEyeTracking=Window.isEyeTracking; %Is eye tracking being used? + +%No longer used in most recent Utils_PlayAV +%InputStruct.isAnticipationError=Conditions.Parameters.isAnticipationError; %Will a sound be played if there is a key press? + +% Make it so a key press terminates the video +% InputStruct.isResponseTermination=1; % No longer used + +% Preset +Data.Timing.TR=[]; +Data.Quit=0; +Quit=Data.Quit; + +%Preset some variables + +Data.MovieChoice={}; +Data.MovieStartTime=[]; + +while Quit == 0 + + PresentationOrder = Conditions.Parameters.FinalStimuli; + + %Put both the block names and stimuli directories in same place so they can + %be iterated through + PresentationOrder(2,:) = Conditions.Parameters.BlockNames; + + Window.EyeTracking = Utils_EyeTracker_Message(Window.EyeTracking, sprintf('Start_of_Block_Time:_%0.3f', GetSecs)); + + fprintf('\n\n -----------------------Start of Block-------------------------- \n\n'); + + %which block was chosen? + ChosenVideo= PresentationOrder(1,ChosenBlock); + + %If you aren't quiting then skip this + if Quit==0 + + %What is the name of the stim selected + ChosenStim={ChosenVideo{1}(4:end)}; + + fprintf('Playing movie: \n\n'); + + %Since you need the base extension for whatever reason here it is + %concatenate strings + Connected = strcat(Conditions.Parameters.BaseExt,ChosenStim); + + %store here + VideoStruct.VideoNames=Connected; + VideoStruct.VideoNames=char(VideoStruct.VideoNames); + + + %Issue message + + Window.EyeTracking = Utils_EyeTracker_Message(Window.EyeTracking, sprintf('Movie_Start_Time:_%0.3f', GetSecs)); + if VideoStruct.WaitforTR == 1 + Utils_EyeTracker_TrialStart(Window.EyeTracking); + end + + VideoStruct.MovieWatched=0; + + + %Store the video name with the starting time + Data.MovieChoice{end+1}=ChosenStim; + Data.MovieStartTime(end+1)=GetSecs; + + %What movie number is this? + MovieCounter=length(Data.MovieStartTime); + + %Store the video struct information. Do so just before playing so + %that Window.NextTR is up to date + VideoStruct.window=Window; + + [Data.Timing.(sprintf('Movie_%d', MovieCounter)), Data.Responses.(sprintf('Movie_%d', MovieCounter)), Data.GazeData.(sprintf('Movie_%d', MovieCounter))]=Utils_PlayAV(VideoStruct, [], TimingStruct, InputStruct); %Plays the movie + + + Window.EyeTracking = Utils_EyeTracker_Message(Window.EyeTracking, sprintf('Movie_Stop_Time:_%0.3f', GetSecs)); + if VideoStruct.WaitforTR == 1 + Utils_EyeTracker_TrialEnd(Window.EyeTracking); + end + + %If the experimenter pressed q during the presentation then return + if (Data.Responses.(sprintf('Movie_%d', MovieCounter)).Quit == 1) + Quit=1; + + %Record whether that this was quit preemptively + Data.Quit=1; + fprintf('\nBlock Terminated\n\n'); + + else + Quit=1; + fprintf('\nExiting experiment because movie has finished\n\n'); + + %Once the movie has finished quit but don't record it as a quit + Data.Quit=0; + end + + + %Append the TR values to the list that grows with every movie + if Window.isfMRI && ~isempty(Data.Timing.(sprintf('Movie_%d', MovieCounter)).TR) + Data.Timing.TR=[Data.Timing.TR, Data.Timing.(sprintf('Movie_%d', MovieCounter)).TR]; + Window.NextTR=Data.Timing.TR(end); + end + + fprintf('\n\nMovie end'); + end + + + Window.EyeTracking = Utils_EyeTracker_Message(Window.EyeTracking, sprintf('End_of_Block_Time:_%0.3f', GetSecs)); + + fprintf('\n\n -----------------------End of Block-------------------------- \n\n'); + + %How long must the console wait before the next sequence can run? Prep it + %only if you waited for the TR at the start + if VideoStruct.WaitforTR + Data.Timing.DecayLapse=Conditions.Parameters.DecayLapse+GetSecs; + else + Data.Timing.DecayLapse=GetSecs; + end +end \ No newline at end of file diff --git a/Scripts/GenerateTrials_CartoonLive.m b/Scripts/GenerateTrials_CartoonLive.m new file mode 100755 index 0000000..19c3faf --- /dev/null +++ b/Scripts/GenerateTrials_CartoonLive.m @@ -0,0 +1,161 @@ +%% Generate Trial sequence and conditions for Cartoon vs. Realistic Movies Experiment +% +% Loads cartoon and live versions of a movie and puts them in a different +% order +% +% Script based off of PlayVideo, MM, etc. +% +% TY 01/26/2022 + +function TrialStructure=GenerateTrials_CartoonLive(varargin) + + +% In case no inputs are given +if nargin > 0 + Window = varargin{4}; +else + Window.ppd = 30; + Window.centerX = 500; + Window.centerY = 500; +end + +Randomise=1; % Do you want to allow the user to choose the order of videos to show (0) or randomly determine the order? + +Parameters.BaseExt=cd; %What is the current folder directory name +Parameters.BaseExt=Parameters.BaseExt(1:max(find(Parameters.BaseExt=='/'))); %Remove the current folder + +Parameters.StimulusDirectory='../Stimuli/CartoonLive/'; %Where are the video stimuli stored? + +Parameters.Preload=0; %Would you like to preload the textures before playing the movie? + +Parameters.DecayLapse=12; %How many seconds will you wait for + + +%Specify the 4 values that define the rectangle of the movie. If the values +%are above zero then they will be treated as pixels, if below zero then it +%will be treated as proportion of the screen +%Parameters.Rect= [0.2, 0.2, 0.8, 0.8]; +ppd_width=22.75*2;% When we originally ran these movies at Princeton we made them 20% of the screen size, which comes out to 22.75 x 12.75 visual degrees. For preservation, the visual angle has been preserved for these analyses. If a movie is not 16:9 then it will be stretched +ppd_height=12.75*2; +x_width = ppd_width/2 * Window.ppd; +y_width = ppd_height/2 * Window.ppd; +Parameters.Rect=[Window.centerX - x_width, Window.centerY - y_width, Window.centerX + x_width, Window.centerY + y_width]; + +%Set up the stimuli for the experiment + +Temp=dir([Parameters.StimulusDirectory, '*.mp4']); %What files are in the video directory + +DirNames=Temp(arrayfun(@(x) ~strcmp(x.name(1),'.'),Temp)); %Remove all hidden files + +for FileCounter=1:length(DirNames) + + if ~isempty(strfind(DirNames(FileCounter).name,'Cartoon')) && isempty(strfind(DirNames(FileCounter).name,'Live')) % if it is the cartoon version + + %Store the movie names + Stimuli.cartoonNames{FileCounter}=[Parameters.StimulusDirectory, DirNames(FileCounter).name]; + + elseif ~isempty(strfind(DirNames(FileCounter).name,'Live')) && isempty(strfind(DirNames(FileCounter).name,'Cartoon')) % if it is the live version + + %Store the movie names + Stimuli.liveNames{FileCounter}=[Parameters.StimulusDirectory, DirNames(FileCounter).name]; + end + +end + +% Now get rid of the empty arrays in there +Stimuli.cartoonNames=Stimuli.cartoonNames(~cellfun(@isempty,Stimuli.cartoonNames)); +Stimuli.liveNames=Stimuli.liveNames(~cellfun(@isempty,Stimuli.liveNames)); + + +% Do a check +if length(Stimuli.cartoonNames) ~= length(Stimuli.liveNames) + warning('There are not equivalent numbers of cartoon and live movies, this will cause issues in counterbalancing. Aborting.') + return +end + +all_stim_names=horzcat(Stimuli.cartoonNames,Stimuli.liveNames); + +% If you don't randomise, the user must choose the condition +if Randomise==0 + + % Ask what condition you want to use + fprintf('\nWhich counterbalancing condition would you like to use? Press a key to continue, or "q" to quit\n') + fprintf(' 1: Cartoon, Live\n 2: Live, Cartoon\n') + + % wait until a valid option + cond_order=-1; + while cond_order==-1 + + pause(0.2); + KbName('UnifyKeyNames'); + [~, keyCode]=KbWait(Window.KeyboardNum); + + % choose the condition order + if strfind(KbName(keyCode), '1')==1 + cond_order=[1,2]; % Cartoon, Live + order_name='Cartoon - Live'; + + elseif strfind(KbName(keyCode), '2')==1 + cond_order=[2,1]; % Live, Cartoon + order_name='Live - Cartoon'; + + elseif strfind(KbName(keyCode), 'q')==1 + fprintf('\nquitting\n') + TrialStructure = []; + return; + + else + fprintf('\nPlease choose a valid option\n') + + end + + pause(0.2); + end + + fprintf('\nUsing counterbalancing condition %s\n',order_name) + +% Else, randomise the order +else + fprintf('\n Randomising the video order\n') + + if rand > 0.5 + cond_order=[1,2]; + order_name='Cartoon - Live'; + else + cond_order=[2,1]; + order_name='Live - Cartoon'; + end + + fprintf('\nUsing counterbalancing condition %s\n',order_name) + +end + +% Order! +Both_ordered = {}; + +for condition_counter=cond_order + Both_ordered{end+1}=all_stim_names{condition_counter}; +end + +% save this out ! +Parameters.FinalStimuli = Both_ordered; + +% Iterate through the blocks and store them based on their name +Parameters.BlockNames = {}; +for movie_path = Both_ordered + + % Pull out just the movie name + movie_name = movie_path{1}(max(strfind(movie_path{1}, '/')) + 1:end-4); + + % Store the name of the block + Parameters.BlockNames{end + 1} = movie_name; +end + +Parameters.BlockNum=length(Parameters.BlockNames); % How many blocks are there + +%Store these +TrialStructure.Parameters=Parameters; +TrialStructure.Stimuli=Stimuli; + + +end \ No newline at end of file