function  [LUT,grayIdx] = make_split_LUT(params)

%MAKE_SPLIT_LUT -- Lookup table with two parts with different resolution.
%   
%  LUT = make_split_LUT(params)
%  [LUT,grayIdx] = make_split_LUT(...)
%
%  The input argument must be a structure with fields 'gamma', 'BRstep',
%  'S_contrast', 'S_domain', 'N_contrast', and 'N_domain' (see LUT_PARAMS).
%  GRAYIDX is a two-element vector: [S_grayIdx N_grayIdx].
%
%  Oftentimes we want to present alternating frames of stimuli and noise.
%  This creates a tradeoff. For the noise we want to utilize the full
%  dynamic range of the monitor (from minimal to maximal luminance).
%  For stimuli such as Gabor patches we want to have fine increments
%  from one intensity level to the next.  The lookup table has only 256
%  entries and cannot support these two desiderata at once.
%
%  MAKE_SPLIT_LUT creates a lookup table LUT with two independent parts.
%  Each part has its own setting on the range-vs-resolution tradeoff as
%  controlled by a 'contrast' parameter.  The two parts are arbitrarily
%  called 'signal' and 'noise'. The parameters 'S_domain' and 'N_domain'
%  specify which entries in the LUT belong to one or the other, resp.
%  The two domains must be disjoint but need not cover all 256 entries.
%
%  'N_contrast' is typically 1.0, which corresponds to full dynamic range.
%  'S_contrast' is a real number b/n 0 and 1 (default 0.25 in LUT_PARAMS).
%  It specifies what fraction of the dynamic range is used for the stimuli.
%  The midpoint of either domain always has intensity halfway between Lmin 
%  and Lmax (that is, 255*(1/2)^(1/gamma)). The remaining entries spread
%  up and down from the midpoint with increments inversely proportional
%  to the contrast. The index of this midpoint is returned in GRAYIDX.
%
%  Each half of the LUT is generated by MAKE_LINEAR_LUT and hence
%  compensates for the non-linearity of the monitor's "gamma function."
%
%  Example:
%    params = LUT_params ;
%    [LUT,grayIdx] = make_split_LUT(params) ;
%    drive_voltage = LUT(:,3) + LUT(:,1)./params.BRstep ;
%    luminance = (drive_voltage./255) .^ params.gamma ;
%    luminance(grayIdx+1)'      % should return [0.500 0.500]
%    subplot(2,1,1) ; plot(drive_voltage,'.');axis([0 256 0 256]);
%    subplot(2,1,2) ; plot(luminance,'.');axis([0 256 0 1]);
%
%  See also MAKE_LINEAR_LUT, LUT_PARAMS.

% Original coding by Alex Petrov, Ohio State University
% $Revision: 1.0 $  $Date: 2001/12/1 17:00 $
%
% Part of the utils toolbox version 1.1 for MATLAB version 5 and up.
% http://alexpetrov.com/softw/utils/
% Copyright (c) Alexander Petrov 1999-2006, http://alexpetrov.com
% Please read the LICENSE and NO WARRANTY statement in ../utils_license.m

if (~isstruct(params))
   error('The argument must be a structure. See function LUT_PARAMS.') ;
end

%-- Call MAKE_LINEAR_LUT to generate each half in turn
linear_params = params ;
grayIdx = [0 0] ;

linear_params.contrast = params.S_contrast ;
linear_params.domain = params.S_domain ;
[LUT,S_gray] = make_linear_LUT(linear_params) ;

linear_params.contrast = params.N_contrast ;
linear_params.domain = params.N_domain ;
[N_LUT,N_gray] = make_linear_LUT(linear_params) ;

%-- Graft the relevant part of N_LUT onto (S)LUT to make the final LUT
N_domain = params.N_domain + 1 ;   % bytes start at 0, MATLAB indices at 1
N_idx = [N_domain(1) : N_domain(2)]' ;
LUT(N_idx,:) = N_LUT(N_idx,:) ;
grayIdx = [S_gray N_gray] ;

%--- Return LUT
%%%%% End of file MAKE_SPLIT_LUT.M
