Browse Source

added stimulation folder

MHK 2 years ago
parent
commit
19d53b7d54
2 changed files with 245 additions and 0 deletions
  1. 245 0
      Stimulation/SpatioTemporal_Binary_White_Noise_Stimulus.m
  2. BIN
      Stimulation/ran1.mexw64

+ 245 - 0
Stimulation/SpatioTemporal_Binary_White_Noise_Stimulus.m

@@ -0,0 +1,245 @@
+
+
+function SpatioTemporal_Binary_White_Noise_Stimulus(varargin)
+%
+%
+%===================================================================================
+% Parameter             Default                         Usage
+%===================================================================================
+%
+% selecttextfile       	false       To call browse prompt to select the parameters text file
+% stixelwidth           6           Width of each pixel of the checkerboard defined in monitor pixels unit
+% stixelheight          6           Height of each pixel of the checkerboard defined in monitor pixels unit
+% blackwhite            true        Option to switch between Binary and Gaussian white-noise (Not available)
+% contrast              1           Contrast of black & white stimulus. 1 is 100 contrast.
+% meanintensity         0.5         Mean intensity value used to define contrast
+% seed                  -1000       Starting value for random number generator (should be always negative)
+% secondseed            -10000  	Same as seed but for green color (only used if color is true).
+% thirdseed             -2000   	Same as seed but for blue color (only used if color is true).
+% nblinks               2           Number of frames to hold the stimulus on screen (2 is 30 Hz stimulus)
+% color                 false   	Option to switch between black & white and chromatic white-noise
+% redmeanintensity  	0           Mean intensity for red gun of the screen (only used if color is true).
+% greenmeanintensity	0.5         Mean intensity for green gun of the screen (only used if color is true).
+% bluemeanintensity     0.5         Mean intensity for blue gun of the screen (only used if color is true).
+% redcontrast           0           Contrast of red stimulus (only used if color is true).
+% greencontrast         0.75        Contrast of green stimulus (only used if color is true).
+% bluecontrast          0.75        Contrast of blue stimulus (only used if color is true).
+% screensize            864 x 480	Screen resolution, default value is the resolution of the lightcrafter projector
+% refreshrate           60      	Screen refresh rate in Hz
+% fullscreen            false       Option to display the stimulus in full-screen mode
+% help                  false       Option to check the list of available parameters
+% lmargin               0           Margins from left side of the screen (not available for this stimulus)
+% rmagin                0           Margins from right side of the screen (not available for this stimulus)
+% tmargin               0       	Margins from top of the screen (not available for this stimulus)
+% bmargin               0       	Margins from bottom of the screen (not available for this stimulus)
+% coneisolating         false       Option to activate opsin-isolation (excluded for simplicity)
+%
+%====================================================================================
+%
+%
+
+para            =   read_stimulus_parameters(varargin{:});
+if para.help, return; end
+
+% xax = (para.lmargin+1):para.stixelwidth:(para.screensize(1)-(para.rmargin));
+% yax = (para.bmargin+1):para.stixelheight:(para.screensize(2)-(para.tmargin));
+
+xax     =   linspace(para.lmargin,para.screensize(1)-(para.rmargin),para.Nx)+para.stixelwidth/2;
+yax     =   linspace(para.tmargin,para.screensize(2)-(para.bmargin),para.Ny)+para.stixelheight/2;
+
+
+% The darwing of the screen goes here
+monitorsize =   get(0,'ScreenSize');
+scpos       =   [monitorsize(3)/2-(para.screensize(1)/2), ...
+    monitorsize(4)/2-(para.screensize(2)/2), para.screensize];
+% make an screen like figure
+fh          =   figure('Menu','none','ToolBar','none','Position',scpos,'Color',0.5*[1 1 1]);
+fh.Name     =   'Example of Spatio-temporal White Noise Stimulus, from Khani and Gollisch (2021)';
+fh.Colormap =   gray;
+ah          =   axes('Units','Normalize','Position',[0 0 1 1],'Color',0.5*[1 1 1]);
+axis(ah,[0, para.screensize(1),0, para.screensize(2)]);
+axis(ah,'off');
+
+
+framecounter    =   0;
+if para.color
+    seed1       =   para.seed;
+    seed2       =   para.secondseed;
+    seed3       =   para.thirdseed;
+    
+    redWeberContrastHigh    = para.redmeanintensity   + (para.redContrast   * para.redmeanintensity);
+    redWeberContrastLow     = para.redmeanintensity   - (para.redContrast   * para.redmeanintensity);
+    greenWeberContrastHigh  = para.greenmeanintensity + (para.greenContrast * para.greenmeanintensity);
+    greenWeberContrastLow   = para.greenmeanintensity - (para.greenContrast * para.greenmeanintensity);
+    blueWeberContrastHigh   = para.bluemeanintensity  + (para.blueContrast  * para.bluemeanintensity);
+    blueWeberContrastLow    = para.bluemeanintensity  - (para.blueContrast  * para.bluemeanintensity);
+    
+else
+    seed        =   para.seed;
+    whiteWeberContrastHigh  = para.meanintensity + (para.contrast * para.meanintensity);
+    whiteWeberContrastLow   = para.meanintensity - (para.contrast * para.meanintensity);
+end
+
+while ishandle(fh)
+    
+    if para.color
+        % red
+        [checkerred, seed1]     =   ran1(seed1,para.Nx*para.Ny);
+        checkerred  =   single((checkerred > para.redmeanintensity) .* redWeberContrastHigh);
+        checkerred(checkerred == 0)  =   redWeberContrastLow;
+        checkerred              =   reshape(checkerred,para.Ny,para.Nx);
+        % green
+        [checkergreen, seed2]   =   ran1(seed2,para.Nx*para.Ny);
+        checkergreen =  single((checkergreen > para.greenmeanintensity) .* greenWeberContrastHigh);
+        checkergreen(checkergreen == 0)     =   greenWeberContrastLow;
+        checkergreen            =   reshape(checkergreen,para.Ny,para.Nx);
+        % blue
+        [checkerblue, seed3]    =   ran1(seed3,para.Nx*para.Ny);
+        checkerblue  =  single((checkerblue > para.bluemeanintensity) .* blueWeberContrastHigh);
+        checkerblue(checkerblue == 0)       =   blueWeberContrastLow;
+        checkerblue             =   reshape(checkerblue,para.Ny,para.Nx);
+        % put all colors together
+        checker                 =   cat(3,checkerred,checkergreen,checkerblue);
+    else
+        % black & white checker
+        [checker, seed]         =   ran1(seed,para.Nx*para.Ny);
+        checker     =   single((checker > para.meanintensity) .* whiteWeberContrastHigh);
+        checker(checker == 0)   =   whiteWeberContrastLow;
+        checker                 =   reshape(checker,para.Ny,para.Nx);
+        checker                 =   repmat(checker,1,1,3);
+    end
+    
+    if framecounter == 0
+        rf                      =   imagesc(xax,yax, checker);
+        axis(ah,[0, para.screensize(1),0, para.screensize(2)]);
+        set(ah,'Color',0.5*[1 1 1]); % this is to have gray background with margins
+    else
+        rf.CData                =   checker;
+    end
+    
+    % this is to draw the frames relatively accurately.
+    drawnow;
+    java.lang.Thread.sleep(para.nblinks/para.refreshrate*1e3);
+    %pause(1/para.refreshrate);
+    framecounter    =   framecounter+1;
+end
+
+end
+
+%--------------------------------------------------------------------------------------------------%
+%----------                               sub-functions                                  ----------%
+%--------------------------------------------------------------------------------------------------%
+
+function paraout = read_stimulus_parameters(varargin)
+
+% first parse the user inputs
+p = inputParser();      % check the user options.
+
+validtruefalse = @(x) islogical(x) || (isnumeric(x) && ismember(x,[0,1]));
+p.addParameter('selecttextfile', false,  validtruefalse);
+p.addParameter('stixelwidth', 6, @isnumeric);
+p.addParameter('stixelheight', 6, @isnumeric);
+p.addParameter('blackwhite', true,  validtruefalse);
+p.addParameter('contrast',1, @isnumeric);
+p.addParameter('meanintensity', 0.5, @isnumeric);
+p.addParameter('seed', -1000, @isnumeric);
+p.addParameter('secondseed', -10000, @isnumeric);
+p.addParameter('thirdseed', -2000, @isnumeric);
+p.addParameter('nblinks', 2, @isnumeric);
+p.addParameter('lmargin',0, @isnumeric);
+p.addParameter('rmargin', 0, @isnumeric);
+p.addParameter('bmargin', 0, @isnumeric);
+p.addParameter('tmargin', 0, @isnumeric);
+p.addParameter('color', false,  validtruefalse);
+p.addParameter('coneisolating', true,  validtruefalse);
+p.addParameter('redmeanintensity', 0, @isnumeric);
+p.addParameter('greenmeanintensity', 0.5, @isnumeric);
+p.addParameter('bluemeanintensity', 0.5, @isnumeric);
+p.addParameter('redContrast', 0, @isnumeric);
+p.addParameter('greenContrast', 0.75, @isnumeric);
+p.addParameter('blueContrast', 0.75, @isnumeric);
+p.addParameter('screensize', [864 480], @isnumeric);
+p.addParameter('refreshrate', 60, @isnumeric);
+p.addParameter('fullscreen', false, validtruefalse);
+p.addParameter('help', false,  validtruefalse);
+
+p.parse(varargin{:});
+% defualt parameters
+defpara     =    p.Results;
+
+if defpara.help
+    help_info_for_parameters(defpara);
+    paraout     =   defpara;
+    return;
+end
+
+if defpara.selecttextfile
+    % now read the text files
+    [stimfile, stimpath] = uigetfile('*.txt','Select a chromatic integration stimulus parameter file','chromatic_integration.txt');
+    
+    fid     =   fopen([stimpath,filesep,stimfile]);
+    tline   =   fgetl(fid);
+    while ischar(tline)
+        tline   =   fgetl(fid);
+        if tline == -1, break; end
+        fn      =   extractBefore(tline,' = ');
+        if isempty(fn), continue; end
+        val     =   extractAfter(tline,' = ');
+        % to convert to double
+        if ~isnan(str2double(val))
+            val =   str2double(val);
+        end
+        % to convert to logical
+        if strcmp(val,'true'),        val = true;       end
+        if strcmp(val,'false'),       val = false;       end
+        % store the values in a structure
+        stimpara.(fn)   =   val;
+    end
+    fclose(fid);
+    
+    % compare the text file to the defualt values and fill the missing parameters
+    fn      =       fieldnames(defpara);
+    for ii  =   1:numel(fn)
+        if isfield(stimpara,fn{ii})
+            paraout.(fn{ii})    =       stimpara.(fn{ii});
+        else
+            paraout.(fn{ii})    =       defpara.(fn{ii});
+        end
+    end
+else
+    paraout     =       defpara;
+end
+
+% stimsize    =   [0+para.bmargin, 0+para.lmargin, para.screensize(1)-para.rmargin,...
+%                 para.screensize(2)-para.tmargin];
+xpixels     =   paraout.screensize(1) - (paraout.lmargin + paraout.rmargin);
+ypixels     =   paraout.screensize(2) - (paraout.tmargin + paraout.bmargin);
+paraout.Nx  =   ceil(xpixels / paraout.stixelwidth);
+paraout.Ny  =   ceil(ypixels / paraout.stixelheight);
+
+if paraout.stixelwidth > xpixels, paraout.stixelwidth = xpixels-1; end
+if paraout.stixelheight > ypixels, paraout.stixelheight = ypixels-1; end
+
+if paraout.fullscreen
+    monitorsize         =   get(0,'ScreenSize');
+    paraout.screensize  =   monitorsize(3:4) ;
+end
+
+end
+
+%--------------------------------------------------------------------------------------------------%
+
+function help_info_for_parameters(defpara)
+
+fn          =   fieldnames(defpara);
+fprintf(['\n\n',repmat('==',1,50),'\r\n']);
+fprintf([repmat(' ',1,35),'List of Stimulus Parameters\r\n']);
+fprintf([repmat('==',1,50),'\r\n']);
+maxtxtlen   =   max(cellfun(@numel,fn))+10;
+for ii      =  1:numel(fn)
+    g       =  repmat(' ',1,maxtxtlen - numel(fn{ii}));
+    fprintf(['\t-- \t%s',g,':',repmat(' ',1,10),'%s\n'],fn{ii},num2str(defpara.(fn{ii})));
+end
+fprintf(['\n',repmat('==',1,50),'\r\n']);
+
+end

BIN
Stimulation/ran1.mexw64