ParSettings.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. function ParSettings
  2. % ParSettings gives all parameters for the experiment in global Par
  3. global Par
  4. global StimObj
  5. %% Setup ==================================================================
  6. % Spinoza_Mock / Spinoza_3T / NIN
  7. if strcmp(Par.ScreenChoice,'3T')
  8. Par.SetUp = 'Spinoza_3T';
  9. elseif strcmp(Par.ScreenChoice,'Mock')
  10. Par.SetUp = 'Spinoza_MOCK';
  11. elseif strcmp(Par.ScreenChoice,'NIN')
  12. Par.SetUp = 'NIN';
  13. end
  14. %% Triggering =============================================================
  15. Par.TR = 2.5; % Not important during training
  16. Par.MRITriggeredStart = false;
  17. Par.MRITrigger_OnlyOnce = true;
  18. %% Get stimulus info ======================================================
  19. eval(Par.STIMSETFILE); % loads the chosen stimfile
  20. Stm=StimObj.Stm;
  21. % overwrites the stimsetting!
  22. StimObj.Stm.FixDotCol = [.3 .3 .3 ; .1 .1 .1]; %[RGB if not fixating; RGB fixating]
  23. % overrule generic fixation window
  24. Par.FixWinSize = [1.5 1.5]; % [W H] in deg
  25. %% Eyetracking parameters =================================================
  26. Par.SetZero = false; %initialize zero key to not pressed
  27. Par.SCx = 0.135; %initial scale in control window
  28. Par.SCy = 0.135;
  29. Par.OFFx = 0; %initial eye offset x => (center) of camera das output
  30. Par.OFFy = 0; %initial eye offset y
  31. Par.ScaleOff = [Par.OFFx; Par.OFFy; Par.SCx; Par.SCy];
  32. %Offx, %Offy, Scalex, Scaley ; offset and scaling of eyechannels
  33. %if using eyelink set to -1.0 else 1.0
  34. Par.xdir = 1;
  35. Par.ydir = 1;
  36. Par.Sdx = 0; %2* standard error on eyechannels in pixels
  37. Par.Sdy = 0;
  38. Par.FixWdDeg = Par.FixWinSize(1);
  39. Par.FixHtDeg = Par.FixWinSize(2);
  40. Par.TargWdDeg = 2;
  41. Par.TargHtDeg = 2;
  42. Par.Bsqr = 0; %use square (1) or ellipse (0 )
  43. Par.MousePress = 2; %0 left = 'normal', 1 middle = 'extend', 2 right = 'alt'
  44. Par.NoiseUpdate = false; %show standard error of noise in fixation period
  45. Par.NoiseUpdate = 0; %calculate noise level
  46. %to use or not use the mouse
  47. if ~exist('Par','var') || ~isfield(Par,'Mouserun')
  48. Par.Mouserun = 0;
  49. Par.MOff(1) = 0; %mouse offsets
  50. Par.MOff(2) = 0;
  51. end
  52. % parameters for interfacing with ISCAN
  53. Par.EyeRecAutoTrigger = false;
  54. Par.EyeRecStatus = 0; % recording status initially to 'not recording'
  55. Par.EyeRecTriggerLevel = 1; % 1 = stop recording, 0 = start recording
  56. %% Screen info ============================================================
  57. [ScrWidth, ScrHeight] = Screen('WindowSize',Par.ScrNr);
  58. Par.HW = ScrWidth/2; %get half width of the screen
  59. Par.HH = ScrHeight/2;
  60. Par.ScrCenter = [Par.HW Par.HH];
  61. [Par.ScreenWidthD2, Par.ScreenHeightD2] = Screen('DisplaySize',Par.ScrNr);
  62. if strcmp(Par.SetUp,'NIN')
  63. Par.DistanceToScreen = 700; % distance to screen in mm
  64. elseif strcmp(Par.SetUp,'Spinoza_MOCK')
  65. Par.DistanceToScreen = 1200; % distance to screen in mm
  66. % physical display size report is unreliable
  67. % these measures are taken by hand
  68. Par.ScreenWidthD2 = 600;
  69. Par.ScreenHeightD2 = 337.5;
  70. elseif strcmp(Par.SetUp,'Spinoza_3T')
  71. Par.DistanceToScreen = 1300; % distance to screen in mm
  72. Par.ScreenWidthD2 = 705;
  73. Par.ScreenHeightD2 = 400;
  74. end
  75. Par.PixPerDeg = Par.HW/atand(Par.ScreenWidthD2/(2*Par.DistanceToScreen));
  76. % CheckFlipRate
  77. hz = Screen('NominalFrameRate', Par.ScrNr); RefRate100=hz*100;
  78. [MeasuredFlip,nrValidSamples,stddev] = ...
  79. Screen('GetFlipInterval',Par.window,100,[],[]);
  80. Rf = 1/MeasuredFlip;
  81. if round(RefRate100/1000) ~= round(Rf/10) %should be approximately the same
  82. disp(['Warning!: refreshrate not properly reported by PTB; ' ...
  83. num2str(RefRate100/100) 'Hz'] )
  84. Par.fliptime = MeasuredFlip*1000; %in ms
  85. else
  86. Par.fliptime = 100000/RefRate100; %fliptime in ms
  87. end
  88. Par.fliptimeSec = Par.fliptime/1000;
  89. Par.nFlipsRefresh=round(Stm(1).FlipTimePredef/Par.fliptimeSec);
  90. if Par.nFlipsRefresh==0 || ~Stm(1).UsePreDefFlipTime
  91. Par.nFlipsRefresh=1;
  92. end
  93. Par.BG = Stm(1).BackColor; % get from stimulus file
  94. Par.ScrWhite=WhiteIndex(Par.window);
  95. Par.ScrBlack=BlackIndex(Par.window);
  96. %% DAS parameters =========================================================
  97. % Bit/port assignment
  98. Par.ErrorB = 0;
  99. Par.StimB = 1;
  100. %Par.TargetB = 2; % check if they're really not used!
  101. %Par.RewardB = 3; % check if they're really not used!
  102. %Par.SaccadeB = 4; done by DasControl do not use for something else!!
  103. %Par.TrialB = 5; done by DasControl
  104. Par.LED_B = [2 3]; % [1/LEFT 2/RIGHT]
  105. Par.MicroB = 6;
  106. Par.CorrectB = 7;
  107. %% Response box ===========================================================
  108. Par.ResponseBox.Type='Lift'; % 'Beam' or'Lift'
  109. %% Response task ==========================================================
  110. Par.ResponseBox.Task = 'DetectGoSignal';
  111. %Par.ResponseBox.Task = 'Fixate'; % doesn't really matter as long as
  112. % it's not DetectGoSignal
  113. Par.RESP_STATE_WAIT = 1; % Go signal not yet given
  114. Par.RESP_STATE_GO = 2; % Go signal given
  115. Par.RESP_STATE_DONE = 4; % Go signal given and response no longer possible (hit or miss)
  116. % Go-bar (vertical / horizontal target bar) -------------------------------
  117. Gobar_length = 0.15; % .02
  118. Par.GoBarSize = Gobar_length*[1, .25] + [0, 0.01]; % [length width] in deg
  119. Par.GoBarColor = [0.6 0.7 0.7]; % [R G B] 0-1
  120. % Color of the Response indicator (which hand)
  121. Par.RespLeverMatters = false;
  122. Par.RespIndColor = 0.1*[1 1 1;1 1 1]; % colors for the left and right target
  123. Par.RespIndSize = 0.3;
  124. Par.RespIndPos = [0 0; 0 0]; % deg
  125. Par.RespIndLeds = false;
  126. Par.DrawNeutralWaitInd = false;
  127. Par.DrawDuringWait_SOA = 0; % s
  128. Par.DrawBlockedInd = false; % indicator to draw when a lever is still up
  129. Par.BlockedIndColor = [.7 .7 .7];
  130. Par.SwitchDur = 1500; % (200) duration of alternative orientation
  131. Par.ResponseAllowed = [80 Par.SwitchDur+100]; % [after_onset after_offset] in ms
  132. Par.PostErrorDelay = 3000; % extra wait time as punishment for error trials
  133. Par.DelayOnMiss = 500; % extra wait time as punishment for miss trials
  134. Par.PostCorrectDelay = 100;
  135. Par.NoIndicatorDuringPunishDelay=true;
  136. Par.ProbSideRepeatOnCorrect = 0.50;
  137. Par.ProbSideRepeatOnError = 0.50;
  138. Par.ProbSideRepeatOnMiss = 0.50;
  139. Par.ProbSideRepeatOnEarly = 0.50;
  140. Par.MaxNumberOfConsecutiveErrors = 1000000;
  141. Par.CatchBlock.do = true;
  142. Par.CatchBlock.AfterNumberOfTrials = 1;
  143. Par.CatchBlock.NoCorrectPerSideNeeded = 10;
  144. Par.CatchBlock.StartWithCatch = true;
  145. % set time-windows in which something can happen (ms)
  146. % [baseduration_without_switch ...
  147. % period_in_which_switch_randomly_occurs]
  148. Par.EventPeriods = [1000 1500]; % Determines Go-bar onset (was 600 to 1600)
  149. %% Connection box port assignment =========================================
  150. Par.ConnectBox.PhotoAmp = [4 5 7 8]; % channels for photo-amps
  151. Par.ConnectBox.EyeRecStat = 6; % channel for eye-tracker signal
  152. Par.ConnectBox.PhotoAmp_Levers = 1:2; % indeces to PhotoAmp channels
  153. Par.ConnectBox.PhotoAmp_HandIn = 3:4; % indeces to PhotoAmp channels
  154. %% Reward scheme ==========================================================
  155. Par.Reward = true; %boolean to enable reward stim bit or not
  156. Par.RewardSound = false; % give sound feedback about reward
  157. Par.RewSndPar = [44100 800 1]; % [FS(Hz) TonePitch(Hz) Amplitude]
  158. Par.RewardFixFeedBack = true;
  159. % RESP_CORRECT = 1;
  160. % RESP_FALSE = 2;
  161. % RESP_MISS = 3;
  162. % RESP_EARLY = 4;
  163. % RESP_BREAK_FIX = 5;
  164. Par.FeedbackSound = [false true false true false];
  165. Par.FeedbackSoundPar = [ ...
  166. 44100 800 1 0.03; ... CORRECT
  167. 44100 300 1 0.03; ... FALSE
  168. 44100 200 1 0.03; ... MISS
  169. 44100 300 1 0.03; ... EARLY
  170. 44100 400 1.5 0.03 ... FIXATION BREAK
  171. ];
  172. % [FS(Hz) TonePitch(Hz) Amplitude Duration]
  173. % duration matches 'open duration'
  174. % Create audio buffers for low latency sounds
  175. % (they are closed in runstim cleanup)
  176. if any(Par.FeedbackSound)
  177. try
  178. InitializePsychSound; % init driver
  179. % if no speakers are connected, windows shuts down the snd device and
  180. % this will return an error
  181. catch
  182. fprintf('There were no audio devices detected. Is the output connected?\n');
  183. end
  184. end
  185. for i=1:size(Par.FeedbackSoundPar,1)
  186. Par.FeedbackSoundSnd(i).Wav=nan;
  187. Par.FeedbackSoundSnd(i).Fs=nan;
  188. Par.FeedbackSoundSnd(i).h = nan;
  189. if Par.FeedbackSound(i)
  190. RewT=0:1/Par.FeedbackSoundPar(i,1):Par.FeedbackSoundPar(i,4);
  191. Par.FeedbackSoundSnd(i).Wav=...
  192. Par.FeedbackSoundPar(i,3)*sin(2*pi*Par.FeedbackSoundPar(i,2)*RewT);
  193. Par.FeedbackSoundSnd(i).Fs=Par.FeedbackSoundPar(i,1);
  194. Par.FeedbackSoundSnd(i).h = PsychPortAudio('Open', 1, [], 2,...
  195. Par.FeedbackSoundSnd(i).Fs, 1);
  196. PsychPortAudio('FillBuffer', Par.FeedbackSoundSnd(i).h, Par.FeedbackSoundSnd(i).Wav);
  197. clc;
  198. end
  199. end
  200. Par.RewardTaskMultiplier = 0.0;
  201. Par.RewardFixMultiplier = 1.0;
  202. % duration matches 'open duration'
  203. Par.RewardType = 0; % Duration: 0=fixed reward, 1=progressive, 2=stimulus dependent
  204. switch Par.RewardType
  205. case 0
  206. Par.RewardTimeSet = 0.040;
  207. case 1
  208. % Alternatively use a progressive reward scheme based on the number of
  209. % preceding consecutive correct responses format as
  210. % rows stating: [nCorrectTrials RewardTime]
  211. Par.RewardTimeSet = [...
  212. 0 0.025;...
  213. 5 0.1;...
  214. 10 0.100;...
  215. 15 0.150;...
  216. 20 0.200];
  217. % NB! this will be overruled once you manually set the reward time
  218. % with the slider in the Tracker window
  219. case 2
  220. Par.RewardTimeSet = 0; %no reward
  221. end
  222. Par.RewardTimeManual = 0.02; % amount of reward when given manually
  223. Par.RewardFixHoldTimeProg = true;
  224. if Par.RewardFixHoldTimeProg
  225. Par.RewardFixHoldTime = [...
  226. 0 1500;...
  227. 5 1250;...
  228. 10 1000;...
  229. 20 750;...
  230. 30 500;...
  231. ];
  232. else
  233. Par.RewardFixHoldTime = 1250; %time to maintain fixation for reward
  234. end
  235. Par.RewardTime=Par.RewardTimeSet;
  236. %% Hand requirements ======================================================
  237. % Require hands in the box (reduces movement?)
  238. Par.HandInBothOrEither = 'Both'; % 'Both' or 'Either'
  239. % Needed for initiation of tracker since it's in the gui now
  240. Par.RewNeeds.HandIsIn = false;
  241. Par.StimNeeds.HandIsIn = false;
  242. Par.FixNeeds.HandIsIn = false;
  243. Par.TrialNeeds.HandIsIn = true; % manual response task
  244. Par.TrialNeeds.LeversAreDown = true; % manual response task
  245. Par.HandOutDimsScreen = false;
  246. Par.HandOutDimsScreen_perc = 0.9; %(0-1, fraction dimming)
  247. % set-up function to check whether to draw stimulus
  248. if Par.StimNeeds.HandIsIn && strcmp(Par.HandInBothOrEither,'Both')
  249. Par.HideStim_BasedOnHandIn = @(Par) ~all(Par.HandIsIn);
  250. elseif Par.StimNeeds.HandIsIn && strcmp(Par.HandInBothOrEither,'Either')
  251. Par.HideStim_BasedOnHandIn = @(Par) ~any(Par.HandIsIn);
  252. else
  253. Par.HideStim_BasedOnHandIn = @(Par) false;
  254. end
  255. % set-up function to check whether to draw fixation
  256. if Par.FixNeeds.HandIsIn && strcmp(Par.HandInBothOrEither,'Both')
  257. Par.HideFix_BasedOnHandIn = @(Par) ~all(Par.HandIsIn);
  258. elseif Par.FixNeeds.HandIsIn && strcmp(Par.HandInBothOrEither,'Either')
  259. Par.HideFix_BasedOnHandIn = @(Par) ~any(Par.HandIsIn);
  260. else
  261. Par.HideFix_BasedOnHandIn = @(Par) false;
  262. end
  263. % set-up function to check whether to allow reward
  264. if Par.RewNeeds.HandIsIn && strcmp(Par.HandInBothOrEither,'Both')
  265. Par.Rew_BasedOnHandIn = @(Par) all(Par.HandIsIn);
  266. elseif Par.RewNeeds.HandIsIn && strcmp(Par.HandInBothOrEither,'Either')
  267. Par.Rew_BasedOnHandIn = @(Par) any(Par.HandIsIn);
  268. else
  269. Par.Rew_BasedOnHandIn = @(Par) true;
  270. end
  271. % functions for lever task
  272. if Par.TrialNeeds.HandIsIn && Par.TrialNeeds.LeversAreDown % hands in / levers down
  273. Par.CanStartTrial = @(Par) (all(Par.HandIsIn) && ~any(Par.LeverIsUp));
  274. elseif Par.TrialNeeds.HandIsIn % only hands in
  275. Par.CanStartTrial = @(Par) all(Par.HandIsIn);
  276. elseif Par.TrialNeeds.LeversAreDown % only levers down
  277. Par.CanStartTrial = @(Par) ~any(Par.LeverIsUp);
  278. else % independent of hand and lever position
  279. Par.CanStartTrial = @(Par) true;
  280. end
  281. Par.CorrectResponseGiven = ...
  282. @(Par) Par.ResponseSide > 0 && Par.BeamIsBlocked(Par.ResponseSide);
  283. Par.IncorrectResponseGiven = ...
  284. @(Par) Par.ResponseSide > 0 && Par.BeamIsBlocked(mod(Par.ResponseSide,2)+1);
  285. % Reward for keeping hand in the box
  286. Par.RewardForHandsIn = false;
  287. Par.RewardForHandsIn_Quant = [0.04 0.08]; % 1 hand, both hands
  288. Par.RewardForHandsIn_MultiplierPerHand = [1.5 1]; % if only one hand in is rewarded [L R]
  289. Par.RewardForHandIn_MinInterval = 2; %s
  290. Par.RewardForHandIn_ResetIntervalWhenOut = false;
  291. Par.RewardForHandIn_MinIntervalBetween = 1; %s
  292. % resets the timer for the next reward when the hand(s) are taken out
  293. % Fixation rewards are multiplied with this factor when hands are in
  294. Par.FixReward_HandInGain = [1 1]; % one hand , both hands
  295. %% Create Eye-check windows based on stimulus positions ===================
  296. % The code below is preloaded and will be overwritten on stimulus basis
  297. % for every trial individually
  298. %example window types, should be replaced by your own control windows
  299. FIX = 0; %this is the fixation window
  300. TALT = 1; %this is an alternative/erroneous target window
  301. TARG = 2; %this is the correct target window
  302. %Par.WIN = [xpos, ypos, pix width, pix height, window type]
  303. Par.WIN = [...
  304. 0, 0, Par.PixPerDeg*Par.FixWdDeg, Par.PixPerDeg*Par.FixHtDeg, FIX; ...
  305. 200, 0, Par.PixPerDeg*Par.TargWdDeg, Par.PixPerDeg*Par.TargHtDeg, TARG; ...
  306. -200, 0, Par.PixPerDeg*Par.TargWdDeg, Par.PixPerDeg*Par.TargHtDeg, TALT].';
  307. %when target and fixation windows change in position and dimension you will
  308. %have to call two functions. The first is to show their position on the tracker screen.
  309. %The second is to update das routines that detect eye movements entering
  310. %and leaving these windows
  311. % 1. ->refreshtracker( 1) %clear tracker screen and set fixation and target windows
  312. % 2. ->SetWindowDas %set das control thresholds using global parameters : Par
  313. %% Trial count inital =====================================================
  314. Par.Trlcount = [0 0]; %[this_position total]
  315. Par.CorrStreakcount = [0 0];
  316. %% Keyboard initialization ================================================
  317. Par.KeyEscape = KbName('Escape'); % allows breaking out of the experiment
  318. Par.KeyTriggerMR = KbName('t'); % MRI sends a sync pulse as a 't' keypress
  319. Par.KeyJuice = KbName('j'); % Manual juice reward
  320. Par.KeyStim = KbName('s'); % toggle stimulus on/off
  321. Par.KeyFix = KbName('f'); % toggle fix dot on/off
  322. Par.KeyPause = KbName('p'); % switch on/off stimuli & reward
  323. Par.KeyRewTimeSet = KbName('r'); % switch to reward timing as defined in ParSettings
  324. Par.KeyShowRewTime = KbName('w'); % Shows the current reward scheme
  325. % using the slider in tracker window overrules the initialize reward timing
  326. % Change stim position
  327. KbName('UnifyKeyNames');
  328. Par.Key1 = KbName('1!');
  329. Par.Key2 = KbName('2@');
  330. Par.Key3 = KbName('3#');
  331. Par.Key4 = KbName('4$');
  332. Par.Key5 = KbName('5%');
  333. % ARROW KEYS, adn 'Z' ARE USED BY TRACKER WINDOW
  334. % Par.KeyNext = KbName('RightArrow');
  335. % Par.KeyPrevious = KbName('LeftArrow');
  336. Par.KeyNext = KbName('n'); % next position
  337. Par.KeyCyclePos = KbName('0)'); % toggle cycle position automatically
  338. Par.KeyLockPos = KbName('l'); % lock current position (switching keys will have no effect)
  339. Par.PositionLocked=true;
  340. Par.KeyBeam = KbName('b'); % cycle through possible beam requirements
  341. Par.KeyBeamInd = 0;
  342. Par.KeyBeamStates = {...
  343. 'BeamState','Both/Either','TrialNeedsHand','FixNeedsHand';...
  344. '1','Both', 1,1;...
  345. '2','Both', 1,0;...
  346. '3','Both', 0,1;...
  347. '4','Either', 1,1;...
  348. '5','Either', 1,0;...
  349. '6','Either', 0,1;...
  350. '7','None', 0,0};
  351. %% Trial timing information (CvdT) ========================================
  352. % NB: Most of this is not used, but tracker may need it in initialization
  353. Par.Times.ToFix = 0; %time to enter fix window in ms
  354. Par.Times.Fix = 0; %Time in fixation window
  355. Par.Times.Stim = 0; %Stimulus on time
  356. Par.Times.Targ = Par.RewardFixHoldTime; %Time to keep fixating after stim onset
  357. Par.Times.TargCurrent = Par.Times.Targ;
  358. Par.Times.Rt = 0; %Time to make eye movement
  359. Par.Times.InterTrial = 0; %intertrial time
  360. Par.Times.RndFix = 0; %max uniform random time to add to stimulus onset time
  361. Par.Times.RndStim = 0; %max uniform random time to add to stimulus display time
  362. Par.Times.RndTarg = 0; %max uniform random time to add to target onset time
  363. Par.Times.Sacc = 0; %max time to finish saccade
  364. Par.Times.Err = 0; %time to add to in RT-epoch after error
  365. %
  366. Par.Drum = false; %drumming on or off, redoing error trials
  367. Par.DrumType = 1; %1=immediately repeat, 2=append to end, 3=insert randomly
  368. Par.isRunning = false; %stimulus presentation off
  369. %% Tracker window control =================================================
  370. Par.ZOOM = 0.52; %control - cogent window zoom
  371. Par.P1 = 1; Par.P2 = 1;
  372. %% Logging ================================================================
  373. Par.PlotPerformance = false;
  374. % log folder should be defined in stimsettings
  375. Par.LogFolder = Stm(1).LogFolder;