/temporal_sens_params.m

https://github.com/bnaecker/temporal-sens · MATLAB · 151 lines · 106 code · 8 blank · 37 comment · 0 complexity · b94de12fb5e296772db99370c017024a MD5 · raw file

  1. function ex = temporal_sens_params(ex, wntime, sens_time, sens_reps, ...
  2. adapt_time, probe_time, ntrials, nrounds)
  3. %
  4. % FUNCTION ex = temporal_sens_params(ex, wntime, sens_time, ...
  5. % adapt_time, probe_time, ntrials, nrounds)
  6. %
  7. % Sets up the stimulus parameters for the pure temporal frequency sensitization
  8. % experiment.
  9. %
  10. % INPUT:
  11. % ex - Experimental structure
  12. % wntime - Length of white noise stimulus block (seconds)
  13. % sens_time - Length of high/low blocks for sensitization stimulus (seconds)
  14. % sens_reps - Number of high/low blocks
  15. % adapt_time - Length of adapt blocks (seconds)
  16. % probe_time - Length of probe blocks (seconds)
  17. % ntrials - Number of adapt/probe trials per block
  18. % nrounds - Number of repetitions of each round
  19. %
  20. % OUTPUT:
  21. % ex - Experimental structure
  22. %
  23. % (c) bnaecker@stanford.edu 2014
  24. % 28 May 2014 - wrote it
  25. % 11 Jun 2014 - adding trials, blocks and sensitization stimulus
  26. %% Initialize the structure
  27. stim = struct();
  28. %% Basic info
  29. stim.name = 'temporal-sens'; % Experiment name
  30. stim.date = datestr(now, 31); % Date, ISO 8601 format
  31. ex.disp.aperture_size = 512; % Size of stimulus aperture
  32. ex.disp.dstrect = CenterRectOnPoint(... % Stimulus destination rectangle
  33. [0 0 ex.disp.aperture_size ex.disp.aperture_size], ...
  34. ex.disp.winctr(1), ex.disp.winctr(2));
  35. ex.disp.waitframes = 2; % Number of frames between monitor flips
  36. ex.disp.pdscale = 0.6; % Scale factor for photodiode signal
  37. flip_time = ex.disp.nominalifi * ex.disp.waitframes; % Nominal time between flips
  38. %% White noise information
  39. % NOTE: White noise stimuli themselves are generated on the fly.
  40. % After the experiment, the full white noise movies are saved, if they
  41. % don't already exist, using `stimdb('add', ...)`. They can be loaded
  42. % again with `stimdb('load', ... )`.
  43. stim.wntime = wntime; % Time the white noise stimulus (seconds)
  44. stim.nwnboxes = 32; % Number of boxes
  45. stim.wncontrast = 0.25; % Contrast of gaussian white noise
  46. stim.nwnframes = round(stim.wntime / flip_time); % Number of frames in the stimulus
  47. %% Basic sensitization stimulus
  48. stim.sens_time = sens_time; % Time of high/low contrast blocks
  49. stim.sens_reps = sens_reps; % Number of repetitions
  50. stim.sens_contrast = [0.35 0.10]; % High/low contrast blocks
  51. stim.nsens_frames_per_contrast = ... % Frames in each contrast
  52. round(stim.sens_time ./ flip_time);
  53. stim.nsens_frames_per_trial = ... % Frames in each trial
  54. sum(stim.nsens_frames_per_contrast);
  55. stim.nsens_frames = sum(stim.nsens_frames_per_trial * ... % Total frames
  56. stim.sens_reps);
  57. %% Temporal sensitization stimulus parameters
  58. stim.adapt_time = adapt_time; % Length of an adapt block (seconds)
  59. stim.probe_time = probe_time; % Length of a probe block (seconds)
  60. stim.ntrials = ntrials; % Number of adapt/probe trials per block
  61. stim.nrounds = nrounds; % Number of rounds
  62. stim.cutoff = 2; % Cutoff frequency for low/high pass filters (see ../notes/kernels)
  63. stim.nbands = 2; % Only using low/high pass bands
  64. stim.adapt_contrast = [0.20 0.40]; % Contrasts for adapting stimulus
  65. stim.probe_contrast = [0.10]; % Contrasts for probe stimulus
  66. stim.nadapt_contrasts = length(stim.adapt_contrast); % Number of adapt contrasts
  67. stim.nprobe_contrasts = length(stim.probe_contrast); % Number of probe contrasts
  68. %% Characteristics of filters used to construct the adapt stimuli
  69. stim.filter_order = 4; % Order of the Butterworth filter used to filter noise into bands
  70. stim.low_cutoff = 0.1; % Cutoff frequency, frequencies below this are zeroed to prevent mean adaptation
  71. %% Compute condition matrix
  72. stim.condition_desc = ... % Strings describing ordering of condition matrix
  73. {'band', 'adapt_contrast', 'probe_contrast'};
  74. stim.condition_list = cartprod(... % Condition matrix
  75. 1:stim.nbands, stim.adapt_contrast, stim.probe_contrast);
  76. stim.nconditions = ... % Number of conditions
  77. size(stim.condition_list, 1);
  78. %% Describe the rounds, which are constructed to have all possible
  79. % transitions between blocks of each unique condition (i.e., all
  80. % transitions A->B where A~=B).
  81. stim.single_round = vec(nchoosek(1:stim.nconditions, 2)');
  82. stim.round_list = repmat(stim.single_round, stim.nrounds, 1);
  83. stim.nblocks_per_round = length(stim.single_round);
  84. %% Compute number of frames
  85. stim.nframes_per_adapt = round(stim.adapt_time / ... % Frames in each adapt trial
  86. flip_time);
  87. stim.nframes_per_probe = round(stim.probe_time / ... % Frames in each probe trial
  88. flip_time);
  89. stim.nframes_per_trial = stim.nframes_per_adapt + ... % Frames in each adapt/probe trial
  90. stim.nframes_per_probe;
  91. stim.nframes_per_block = stim.nframes_per_trial * ... % Frames in each condition block
  92. stim.ntrials;
  93. stim.nframes_per_round = stim.nframes_per_block * ... % Frames in each round
  94. stim.nblocks_per_round;
  95. %% Compute ostensible total experiment time. Actual time will diverge slightly,
  96. % due to deviations in the true inter-frame interval.
  97. stim.exp_length = stim.wntime + ...
  98. (sum(stim.sens_time) * stim.sens_reps) + ...
  99. ((stim.adapt_time + stim.probe_time) * stim.ntrials) * ...
  100. stim.nblocks_per_round * stim.nrounds;
  101. %% Create a PRNG for the basic sensitization stimulus
  102. stim.sens_rn = getrng();
  103. stim.sens_rnseed = get(stim.sens_rn, 'Seed');
  104. stim.sens_rnstate = get(stim.sens_rn, 'State');
  105. %% Create a PRNG for the temporal sensitization stimulus
  106. stim.rn = getrng();
  107. stim.rnseed = get(stim.rn, 'Seed');
  108. stim.rnstate = get(stim.rn, 'State');
  109. %% Create the basic sensitization stimulus, with contrasts
  110. stim.sens_stim = ...
  111. [randn(stim.sens_rn, stim.nsens_frames_per_contrast(1), stim.sens_reps) ...
  112. * stim.sens_contrast(1); ...
  113. randn(stim.sens_rn, stim.nsens_frames_per_contrast(2), stim.sens_reps) * ...
  114. stim.sens_contrast(2)];
  115. %% Create the white noise probe stimuli, without resetting the PRNG state
  116. % so that the probe and filtered adapter are uncorrelated.
  117. stim.probe = randn(stim.rn, stim.nrounds, stim.nblocks_per_round, ...
  118. stim.ntrials, stim.nframes_per_probe);
  119. %% Initialize the VBL timestamp arrays
  120. ex.disp.wnvbl = zeros(stim.nwnframes, 1); % VBL for white noise block
  121. ex.disp.sens_vbl = zeros(stim.nsens_frames_per_trial, ... % VBL for basic sens trials
  122. stim.sens_reps);
  123. ex.disp.adapt_vbl = zeros(stim.nrounds, ... % VBL for adapting blocks
  124. stim.nblocks_per_round, stim.ntrials, stim.nframes_per_adapt);
  125. ex.disp.probe_vbl = zeros(stim.nrounds, ... % VBL for probe blocks
  126. stim.nblocks_per_round, stim.ntrials, stim.nframes_per_probe);
  127. ex.disp.flipmissed = []; % Array to hold index of any missed flips
  128. %% Initialize call to GetSecs MEX-function
  129. GetSecs();
  130. %% Attach stim substructure to experimental structure
  131. ex.stim = stim;
  132. %% Set smaller Screen font size, for printing condition description to the monitor
  133. Screen('TextSize', ex.disp.winptr, 18);