THINGS_monkeyF_20240109_B4_runstim.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. function runstim_THINGS(T_Trl)
  2. global Par %global parameters
  3. Par.Mouserun = 0;
  4. dasusemouse( 0 );
  5. preloaded_pics = 40;
  6. ncount = 4;
  7. monkey = 'monkeyF';
  8. % cogstd('sPriority','high')
  9. LOG.fn = 'runstim_THINGS';
  10. DateString = datestr(now,'yyyymmddHHMMSS'); % get date-timestamp
  11. ds_yyyymmdd = DateString(1:8); % date for session
  12. logs_dir = ['\\vs03\VS03-VandC-3\THINGS\Passive_fixation\',monkey,'\_logs\'];
  13. data_dir = ['\\vs03\VS03-VandC-3\THINGS\Passive_fixation\',monkey,'\',ds_yyyymmdd,'\'];
  14. fn_randtab = [logs_dir,'RANDTAB_THINGS_',monkey,'.mat'];
  15. fn_paths = [logs_dir,'things_imgs.mat'];
  16. load(fn_paths)
  17. load(fn_randtab)
  18. fn = input('Enter BLOCK number (e.g. 1), blank = don"t save logs\n','s');
  19. if ~isempty(fn)
  20. if ~exist(data_dir, 'dir')
  21. mkdir(data_dir);
  22. end
  23. %Copy the run stime
  24. logname = ['THINGS_',monkey,'_',ds_yyyymmdd,'_B',fn];
  25. fnrs = [logs_dir,logname,'_','runstim.m'];
  26. disp(['logfile: ',logname])
  27. cfn = [mfilename('fullpath') '.m'];
  28. copyfile(cfn,fnrs)
  29. block_dir = [data_dir,'Block_',fn,'\'];
  30. if ~exist(block_dir, 'dir')
  31. mkdir(block_dir);
  32. end
  33. %Save json metadata
  34. json.version = '1.0';
  35. json.project = 'THINGS';
  36. json.dataset = 'passive_fixation';
  37. json.date = ds_yyyymmdd;
  38. json.subject = monkey;
  39. json.investigator = 'Paolo_Papale';
  40. json.setup = 'RN3s130';
  41. json.condition = 'awake';
  42. json.stimulus = 'natural_images';
  43. json.logfile = logname;
  44. savejson('', json, [block_dir,logname,'_session.json']);
  45. end
  46. if isempty(fn)
  47. logon = 0;
  48. else
  49. logon = 1;
  50. fn_randtab_hist = [logs_dir,'RANDTAB_',logname,'.mat'];
  51. fn = [logs_dir,'THINGS_',monkey,'_',ds_yyyymmdd,'_B',fn];
  52. save(fn,'LOG')
  53. end
  54. %Tracker times
  55. FIXT = 200; %time to fix before stim onset
  56. STIMT = 200; %Exposure
  57. ITI_short = 200;
  58. ITI = 200;
  59. FixWinSizex = 1.0; %1.1
  60. FixWinSizey = 1.0; %1.1
  61. rand('state',sum(clock))
  62. cgfont('Arial' ,30)
  63. %Global properties
  64. frame = 1./85;
  65. FixDotSize = 0.3;
  66. FixPix = Par.PixPerDeg.*FixDotSize;
  67. Px = 0;
  68. Py = 0;
  69. picx = 100;
  70. picy = -100;
  71. %Set grey to be halfway between darkest and brightest luminace to acheive
  72. %maxuimum possible contrast range
  73. %gammacon converts between rgb and luminace given the known gamma curve of
  74. %the montior
  75. % maxlum = gammacon2(1,'rgb2lum');
  76. % minlum = gammacon2(0,'rgb2lum');
  77. % greylum = (maxlum+minlum)./2;
  78. % grey = gammacon2(greylum,'lum2rgb');
  79. grey = .5;
  80. Par.grey = grey;
  81. Times = Par.Times; %copy timing structure
  82. %timing
  83. PREFIXT = Times.ToFix; %time to enter fixation window
  84. %Create log file
  85. LOG.Par = Par;
  86. LOG.Times = Times;
  87. LOG.Frame = frame;
  88. LOG.FIXT = FIXT;
  89. LOG.STIMT = STIMT;
  90. LOG.ScreenX = 1024;
  91. LOG.Screeny = 768;
  92. %pre-LOAD n-imgs imgs
  93. all_remainings = 1:size(RANDTAB,1);
  94. for p = 1:preloaded_pics
  95. if RANDTAB(p,2) > 0
  96. trl = RANDTAB(p,2);
  97. cgloadbmp(p,train_imgs(trl).local_path);
  98. else
  99. trl = RANDTAB(p,3);
  100. cgloadbmp(p,test_imgs(trl).local_path)
  101. end
  102. end
  103. [~] = input('Ready? Press ENTER to start!');
  104. %////YOUR STIMULATION CONTROL LOOP /////////////////////////////////
  105. Hit = 2;
  106. TZ = 0;
  107. Par.ESC = false; %escape has not been pressed
  108. while ~Par.ESC
  109. %Windows (fix and target)
  110. WIN = [0 0 Par.PixPerDeg.*FixWinSizex Par.PixPerDeg.*FixWinSizey 0];
  111. Par.WIN = WIN';
  112. %/////////////////////////////////////////////////////////////////////
  113. %START THE TRIAL
  114. %set control window positions and dimensions
  115. refreshtracker(1) %for your control display
  116. SetWindowDas %for the dascard
  117. Abort = false; %whether subject has aborted before end of trial
  118. ncount_done = 0;
  119. sprites_to_delete = [];
  120. %///////// EVENT 0 START FIXATING //////////////////////////////////////
  121. Par.Updatxy = 1;
  122. cgellipse(Px,Py,FixPix,FixPix,[1,0,0],'f') %the red fixation dot on the screen
  123. drawdiode(0) %the diode cue
  124. cgflip(grey,grey,grey)
  125. dasreset(0)
  126. %subject has to start fixating central dot
  127. Par.SetZero = false; %set key to false to remove previous presses
  128. Par.Updatxy = 1; %centering key is enabled
  129. Time = 1;
  130. Hit = 0;
  131. while Time < PREFIXT && Hit == 0
  132. dasrun(5)
  133. [Hit Time] = DasCheck; %retrieve position values and plot on Control display
  134. end
  135. %///////// EVENT 1 KEEP FIXATING or REDO ////////////////////////////////////
  136. Par.Updatxy = 1;
  137. if Hit ~= 0 %subjects eyes are in fixation window keep fixating for FIX time
  138. dasreset(1); %test for exiting fix window
  139. Time = 1;
  140. Hit = 0;
  141. while Time < FIXT && Hit == 0
  142. %Check for 5 ms
  143. dasrun(5)
  144. %or just pause for 5ms?
  145. [Hit Time] = DasCheck;
  146. end
  147. if Hit ~= 0 %eye has left fixation to early
  148. %possibly due to eye overshoot, give another chance
  149. dasreset(0);
  150. Time = 1;
  151. Hit = 0;
  152. while Time < PREFIXT && Hit == 0
  153. dasrun(5)
  154. [Hit Time] = DasCheck; %retrieve position values and plot on Control display
  155. end
  156. if Hit ~= 0 %subjects eyes are in fixation window keep fixating for FIX time
  157. dasreset(1); %test for exiting fix window
  158. Time = 1;
  159. Hit = 0;
  160. while Time < FIXT && Hit == 0
  161. %Check for 5 ms
  162. dasrun(5)
  163. % dasrun(5)
  164. [Hit Time] = DasCheck;
  165. end
  166. else
  167. Hit = -1; %the subject did not fixate
  168. end
  169. end
  170. else
  171. Hit = -1; %the subject did not fixate
  172. end
  173. %///////// EVENT 2 DISPLAY STIMULUS //////////////////////////////////////
  174. if Hit == 0 %subject kept fixation, display stimulus
  175. Par.Updatxy = 1;
  176. for count = 1:ncount
  177. TrialPic = all_remainings(1);
  178. dasreset(1); %test for exiting fix window
  179. Time = 0;
  180. %StimFlg = true;
  181. stimbitdone = 0;
  182. stimcorrdone = 0;
  183. while Time < STIMT+ITI_short && Hit == 0 %Keep fixating till target onset
  184. if Time < STIMT %present stim no longer than stim time
  185. cgdrawsprite(TrialPic,picx,picy);
  186. cgellipse(Px,Py,FixPix,FixPix,[1,0,0],'f'); %the red fixation dot on the screen
  187. drawdiode(1); %the diode cue
  188. if ~stimbitdone
  189. dasbit(Par.StimB, 1);
  190. stimbitdone = 1;
  191. %This means file will be created
  192. %Update counter
  193. end
  194. end
  195. %..............................................................
  196. if Time > STIMT %&& StimFlg %present stim no longer than stim time
  197. if ~stimcorrdone
  198. dasbit(Par.CorrectB, 1);
  199. Par.Corrcount = Par.Corrcount + 1;
  200. stimcorrdone = 1;
  201. end
  202. %StimFlg = false;
  203. cgellipse(Px,Py,FixPix,FixPix,[1,0,0],'f'); %the red fixation dot on the screen
  204. drawdiode(0); %the diode cue
  205. end
  206. cgflip(grey,grey,grey);
  207. %Check for 5 ms
  208. dasrun(2); %%%%%%%%%%%%%%% was 2
  209. [Hit Time] = DasCheck;
  210. end
  211. if stimbitdone
  212. TZ = TZ+1;
  213. if stimcorrdone
  214. ncount_done = ncount_done + 1;
  215. sprites_to_delete = [sprites_to_delete TrialPic];
  216. MAT(TZ,:) = [RANDTAB(1,:) count 1];
  217. if size(RANDTAB,1) == 1
  218. save(fn,'*');
  219. end
  220. RANDTAB(1,:) = [];
  221. all_remainings(1) = [];
  222. else
  223. MAT(TZ,:) = [RANDTAB(1,:) count 0];
  224. end
  225. end
  226. for i = [0 1 2 3 4 5 6 7] %Error, Stim, Saccade, Trial, Correct,
  227. dasbit(i, 0);
  228. end
  229. dasclearword;
  230. end
  231. %///////// EVENT 3 TARGET ONSET, REACTION TIME //////////////////////////////////////
  232. Par.Updatxy = 1;
  233. if Hit == 0 %subject kept fixation, subject may make an eye movement
  234. cgellipse(Px,Py,FixPix,FixPix,[1,0,0],'f') %the red fixation dot on the screen
  235. cgflip(grey,grey,grey);
  236. Hit = 2;
  237. else
  238. Abort = true;
  239. end
  240. %END EVENT 3
  241. else
  242. Abort = true;
  243. end
  244. %END EVENT 2
  245. for i=1:ncount_done
  246. p = preloaded_pics + sprites_to_delete(i);
  247. r_idx = preloaded_pics - ncount_done + i;
  248. if r_idx <= size(RANDTAB,1)
  249. cgfreesprite(sprites_to_delete(i))
  250. if RANDTAB(r_idx,2) > 0
  251. trl = RANDTAB(r_idx,2);
  252. cgloadbmp(p,train_imgs(trl).local_path);
  253. else
  254. trl = RANDTAB(r_idx,3);
  255. cgloadbmp(p,test_imgs(trl).local_path);
  256. end
  257. end
  258. end
  259. %///////// POSTTRIAL AND REWARD //////////////////////////////////////
  260. if Hit ~= 0 && ~Abort %has entered a target window (false or correct)
  261. if Par.Mouserun
  262. HP = line('XData', Par.ZOOM * (LPStat(2) + Par.MOff(1)), 'YData', Par.ZOOM * (LPStat(3) + Par.MOff(2)), 'EraseMode','none');
  263. else
  264. HP = line('XData', Par.ZOOM * LPStat(2), 'YData', Par.ZOOM * LPStat(3), 'EraseMode','none');
  265. end
  266. set(HP, 'Marker', '+', 'MarkerSize', 20, 'MarkerEdgeColor', 'm');
  267. if Hit == 2
  268. dasbit(Par.RewardB, 1);
  269. dasjuice(8);
  270. pause(Par.RewardTime); %RewardTime is in seconds
  271. dasjuice(0.0);
  272. dasbit(Par.RewardB, 0);
  273. else
  274. Hit = 0;
  275. end
  276. %keep following eye motion
  277. dasrun(5);
  278. DasCheck; %keep following eye motion
  279. end
  280. %///////////////////////INTERTRIAL AND CLEANUP
  281. %reset all bits to null
  282. for i = [0 1 2 3 4 5 6 7] %Error, Stim, Saccade, Trial, Correct,
  283. dasbit(i, 0);
  284. end
  285. dasclearword;
  286. %Par.Trlcount = Par.Trlcount + 1; %counts total number of trials for this session
  287. %tracker('update_trials', gcbo, [], guidata(gcbo)) %displays number of trials, corrects and errors
  288. Par.Trlcount = Par.Trlcount + 1; %counts total number of trials for this session
  289. SCNT = {'TRIALS'};
  290. SCNT(2) = { ['N: ' num2str(Par.Trlcount) ]};
  291. SCNT(3) = { ['C: ' num2str(Par.Corrcount) ] };
  292. SCNT(4) = { ['E: ' num2str(Par.Errcount) ] };
  293. set(T_Trl, 'String', SCNT ) %display updated numbers in GUI
  294. cgflip(grey,grey,grey)
  295. Time = 0;
  296. dasreset(1);
  297. while Time < ITI
  298. dasrun(5)
  299. [Hit Time] = DasCheck;
  300. end
  301. if TZ > 0
  302. save(fn,'LOG','MAT','RANDTAB')
  303. end
  304. end %WHILE_NOT_ESCAPED%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  305. if TZ > 0
  306. save(fn,'*')
  307. if logon
  308. save(fn_randtab,'RANDTAB')
  309. save(fn_randtab_hist,'RANDTAB')
  310. end
  311. end
  312. cogstd('sPriority','normal')