presentStaticGratings_Rapid.m 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. function presentStaticGratings_Rapid()
  2. % Save Directory
  3. sDir= 'X:\Brian';
  4. %%%%%% ver 3 %%%%%%%%%
  5. % added flashing diode at beginning and end of stim presentation
  6. % added closall screen command at end
  7. % added esc key press to terminate session early
  8. Screen('Preference', 'SkipSyncTests', 1)
  9. Screen('Preference', 'VisualDebugLevel', 1);
  10. % in seconds
  11. stimDuration = 250/1000; % stimulus duration in ms, no rest between
  12. isiDuration = 0; % no gray screen between stimulus blocks, set to zero
  13. initialDuration = 2000/1000;
  14. screenDistance = 25; % cm;
  15. numRepeats = 4;
  16. % create a grating parameter table
  17. spfreq_range = 0.02:0.02:0.3;% range of spatial frequencies
  18. angle_range = 0:15:165;% range of angles to use
  19. gratingindexcount = 0;
  20. for spfreqind = 1:length(spfreq_range)
  21. for angleind = 1:length(angle_range)
  22. gratingindexcount = gratingindexcount + 1;
  23. grating_space(gratingindexcount,1) = gratingindexcount;
  24. grating_space(gratingindexcount,2) = angle_range(angleind);
  25. grating_space(gratingindexcount,3) = spfreq_range(spfreqind);
  26. end
  27. end
  28. for repeatind = 1:numRepeats
  29. randomOrder(:,repeatind) = randperm(size(grating_space,1))';
  30. end
  31. randomOrder = randomOrder(:);
  32. % sine wave amplitude ("contrast"), 0.5 = black-white (balanced), 0.0 = full gray
  33. amplitude = 0.5;
  34. sine_params.amplitude=amplitude;
  35. sine_params.grating_space=grating_space;
  36. %% ---------------------------------------------------------
  37. sca;
  38. % Here we call some default settings for setting up Psychtoolbox
  39. PsychDefaultSetup(2);
  40. HideCursor;
  41. screens = Screen('Screens');
  42. % Draw we select the maximum of these numbers. So in a situation where we
  43. % have two screens attached to our monitor we will draw to the external
  44. % screen. When only one screen is attached to the monitor we will draw to
  45. % this.
  46. % For help see: help max
  47. screenNumber = max(screens);
  48. % Define black (white will be 1 and black 0). This is because
  49. % luminace values are (in general) defined between 0 and 1.
  50. % For help see: help BlackIndex
  51. white=WhiteIndex(screenNumber);
  52. black=BlackIndex(screenNumber);
  53. gray=(white+black)/2;
  54. % Open an on screen window and color it black
  55. % For help see: Screen OpenWindow?
  56. [window, windowRect] = PsychImaging('OpenWindow', screenNumber, black);
  57. % Get the size of the on screen window in pixels
  58. % For help see: Screen WindowSize?
  59. [screenXpixels, screenYpixels] = Screen('WindowSize', window);
  60. pixPerCM_width= screenXpixels/64.135;%64.135
  61. pixPerCM_height= screenYpixels/40.01;%40.01
  62. %Get center of screen
  63. %[xCenter, yCenter] = RectCenter(windowRect);
  64. diode = 1;
  65. if diode
  66. diodeDest = [0 0 60 60];
  67. diodeOn= ones(60,60)*white;
  68. diodeOn_tex=Screen('MakeTexture', window, diodeOn);
  69. diodeOff= ones(60,60)*black;
  70. diodeOff_tex=Screen('MakeTexture', window, diodeOff);
  71. end
  72. % Make a base Rect of 200 by 200 pixels. This is the rect which defines the
  73. % size of our square in pixels. Rects are rectangles, so the
  74. % sides do not have to be the same length. The coordinates define the top
  75. % left and bottom right coordinates of our rect [top-left-x top-left-y
  76. % bottom-right-x bottom-right-y]. The easiest thing to do is set the first
  77. % two coordinates to 0, then the last two numbers define the length of the
  78. % rect in X and Y. The next line of code then centers the rect on a
  79. % particular location of the screen.
  80. %set up gray screen with diode
  81. Screen('FillRect',window,gray);
  82. Screen('DrawTexture', window, diodeOff_tex, [], [diodeDest],[]);
  83. Screen('Flip', window);
  84. % add
  85. while ~KbCheck
  86. % wait to start the stim set
  87. end
  88. %want to flicker diode to signal start of session
  89. diodeTargetDuration = 1500/1000;
  90. diodeFlickerFreqHz = 5;
  91. % how long each pattern is shown continuously
  92. diode_flicker_duration = 1/diodeFlickerFreqHz;
  93. % we set the actual stimulus block duration as a multiple of requested flickering frequency
  94. diode_flickers_per_block = ceil(diodeFlickerFreqHz*diodeTargetDuration); %inter stimulus interval
  95. STARTTIME = tic;
  96. diode_timestamps=nan(1,10000);
  97. diode_states=nan(1,10000);
  98. FLIPCOUNT = 0;
  99. for i=1:diode_flickers_per_block
  100. tic
  101. if mod(i,2)==0
  102. diodeColor = diodeOn_tex;
  103. else
  104. diodeColor = diodeOff_tex;
  105. end
  106. Screen('DrawTexture', window, diodeColor, [], [diodeDest],[]);
  107. Screen('Flip',window);
  108. FLIPCOUNT=FLIPCOUNT+1;diode_timestamps(FLIPCOUNT)=toc(STARTTIME);diode_states(FLIPCOUNT)=mod(i,2);
  109. WaitSecs(diode_flicker_duration-toc);
  110. end
  111. %find the refresh rate of the screen in seconds
  112. Screen('FillRect',window,gray);
  113. Screen('DrawTexture', window, diodeOff_tex, [], [diodeDest],[]);
  114. Screen('Flip', window);
  115. ifi = Screen('GetFlipInterval', window);
  116. onedegree = 2*screenDistance*tand(0.5);
  117. onecm = pixPerCM_width;
  118. % Phase is the phase shift in degrees (0-360 etc.)applied to the sine grating:
  119. % Compute increment of phase shift per redraw:
  120. % Build a procedural sine grating texture for a grating with a support of
  121. % res x res pixels and a RGB color offset of 0.5 -- a 50% gray.
  122. [w,h]=Screen('WindowSize',screenNumber);
  123. res=ceil(sqrt(w^2+h^2));
  124. gratingtex = CreateProceduralSineGrating(window,res, res, [0.5 0.5 0.5 0.0]);%,(13/10)*screenYpixels/2
  125. WaitSecs(initialDuration);
  126. DIODESTATE = 0;
  127. fprintf('\nStarting loop\n\n');
  128. %begin stimulus presentation
  129. stimNumber = length(randomOrder);
  130. Phase = 0;
  131. for r=1:stimNumber
  132. DIODESTATE = mod(DIODESTATE+1,2);
  133. FLIPCOUNT=FLIPCOUNT+1;diode_timestamps(FLIPCOUNT)=toc(STARTTIME);diode_states(FLIPCOUNT)=DIODESTATE;
  134. tic;
  135. Screen('DrawTexture', window, gratingtex,[],[],180-grating_space(randomOrder(r),2),[],[],[],[],[],[Phase,grating_space(randomOrder(r),3)/onedegree/onecm,amplitude,0]);
  136. if DIODESTATE==1
  137. Screen('DrawTexture', window, diodeOn_tex, [], [diodeDest],[]);
  138. else
  139. Screen('DrawTexture', window, diodeOff_tex, [], [diodeDest],[]);
  140. end
  141. Screen('Flip', window);
  142. pause(stimDuration);
  143. t=toc;
  144. %fprintf('Block %i duration was %fms, diode state %i\n',r,t*1000,DIODESTATE);
  145. if KbCheck
  146. sca;
  147. return;
  148. end
  149. end
  150. Screen('FillRect',window,gray);
  151. Screen('DrawTexture', window, diodeOff_tex, [], [diodeDest],[]);
  152. Screen('Flip', window);
  153. endPause = initialDuration;
  154. WaitSecs(endPause);
  155. %save data
  156. %flash diode
  157. for i=1:diode_flickers_per_block
  158. tic
  159. if mod(i,2)==0
  160. diodeColor = diodeOn_tex;
  161. else
  162. diodeColor = diodeOff_tex;
  163. end
  164. Screen('DrawTexture', window, diodeColor, [], [diodeDest],[]);
  165. Screen('Flip',window);
  166. FLIPCOUNT=FLIPCOUNT+1;diode_timestamps(FLIPCOUNT)=toc(STARTTIME);diode_states(FLIPCOUNT)=mod(i,2);
  167. WaitSecs(diode_flicker_duration-toc);
  168. end
  169. Screen('FillRect',window,gray);
  170. Screen('DrawTexture', window, diodeOff_tex, [], [diodeDest],[]);
  171. Screen('Flip', window);
  172. FLIPCOUNT=FLIPCOUNT+1;diode_timestamps(FLIPCOUNT)=toc(STARTTIME);diode_states(FLIPCOUNT)=0;
  173. diode_timestamps(FLIPCOUNT+1:end)=[];
  174. diode_states(FLIPCOUNT+1:end)=[];
  175. params.stimType='HARTLEY_linearorispfreq_bj_02to3.m';
  176. params.initialDuration= initialDuration;
  177. params.isiDuration= isiDuration;
  178. params.stimDuration= stimDuration;
  179. params.stimNumber= stimNumber;
  180. params.blockId = randomOrder;
  181. params.AllBlocks=grating_space;
  182. params.StimBlocks = grating_space;
  183. params.diode_timestamps = diode_timestamps;
  184. params.diode_states = diode_states;
  185. spath=pwd;%'C:\Users\skVisStim2\Documents\MATLAB\JanneProjectStimuli\savedParamFiles\';
  186. %spath='P:\Pati\Scripts\SaveFileTesting\';j
  187. datetimename= datestr(now, 'yyyy-mm-dd_HHMMSS');
  188. sname=['locomotionExperiment_HARTLEY_' datetimename];
  189. save([spath,filesep,sname,'.mat'],'initialDuration','isiDuration','stimDuration','stimNumber','randomOrder','grating_space');
  190. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sk saving helper
  191. %
  192. currdir= pwd;
  193. cd (sDir);
  194. listDir= dir;
  195. indx= find([listDir.isdir]);
  196. listDir= listDir(indx);
  197. listDir= listDir(arrayfun(@(x) x.name(1), listDir) ~= '.');
  198. dirDatenum= [listDir.datenum];
  199. [~,indx]= sort(dirDatenum, 'descend');
  200. listDir= listDir(indx);
  201. saveFolder_2pComputer= listDir(1).name;
  202. saveFolder_2pComputer= [sDir '\' saveFolder_2pComputer];
  203. cd(saveFolder_2pComputer)
  204. listDirFiles= dir;
  205. listDirFiles= listDirFiles(arrayfun(@(x) x.isdir(1), listDirFiles) == 0);
  206. listDirFiles= listDirFiles(arrayfun(@(x) x.name(1), listDirFiles ) ~= '.');
  207. s=struct2cell(listDirFiles);
  208. s=s(1,:);
  209. indS= strfind(s, '.sbx');
  210. indS= find(~cellfun(@isempty,indS));
  211. listDirFiles= listDirFiles(indS);
  212. dirFilesDatenum= [listDirFiles.datenum];
  213. [~,indx]= sort(dirFilesDatenum, 'descend');
  214. listDirFiles= listDirFiles(indx);
  215. savePrefixSharingName= listDirFiles(1).name;
  216. saveSharingName= [savePrefixSharingName(1:end-4) '_vsParam'];
  217. cd(currdir)
  218. % sk added Aug 2016
  219. outFileName= saveSharingName;
  220. % outFileName='visStimParams'; params.test=1;
  221. try
  222. if strfind(listDir(1).date, date)
  223. %mkdir(saveFolder_2pComputer,'visStim' )
  224. save([saveFolder_2pComputer '\' outFileName], '-STRUCT','params');
  225. disp('saved vis stim params on 2-P aq computer at location:')
  226. disp([saveFolder_2pComputer '\' outFileName])
  227. else
  228. disp('no new folder made today, please transfer param file manually.');
  229. end
  230. catch
  231. disp('Not sharing volume with PC, please transfer param file manually.');
  232. end
  233. while ~KbCheck
  234. % wait to start the stim set
  235. end
  236. %
  237. ShowCursor;
  238. Screen('CloseAll');