function [XYZ,inputs] = hdrCalibrate(lcdLevels,ledLevels,patchSize,rgb)
% 
% Usage: [XYZ,inputs] = hdrCalibrate([lcdLevels],[ledLevels],[patchSize],[rgb])
% 
% This function measures the CIE XYZ of the specified combinations of
% lcdLevels and ledLevels, with a rectangular patch of size given in
% patchSize put at the center of the HDR display with the selected
% channel(s) (rgb).
% 
% Inputs:
% 1. lcdLevels - a vector specifying the LCD levels to be used; default =
% [0:16:240,255]
% 2. ledLevels - a vector specifying the LED levels to be used; default =
% [0:10:150]
% 3. patchSize - a vector of length 2 specifying the numbers of LEDs
% left/right and above/below the center; default = [1,4]
% 4. rgb - a vector of length 3 specifying which channels to turn on;
% default = [1 1 1]
% 
% Outputs:
% 1. XYZ - a 3-column matrix storing the CIE XYZ values
% 2. inputs - a 2-column matrix storing the LCD (1st column) and LED (2nd
% column) values
% 
% History:
% 03/14/06 shc (shcheung@stanford.edu) wrote it.
tic
if(~exist('lcdLevels','var') | isempty(lcdLevels))
    lcdLevels = [0:16:240,255];
end
if(~exist('ledLevels','var') | isempty(ledLevels))
    ledLevels = [0:10:150];
end
if(~exist('patchSize','var') | isempty(patchSize))
    patchSize = [1,4];
end
if(~exist('rgb','var') | isempty(rgb))
    rgb = [1 1 1];
end

% Initialize the PR650
ieClearSerialPorts;
if(ieNotDefined('nCommPort'))
    nCommPort=4;
end

% Make sure it works
try
    PR650 = cmeter(nCommPort);
catch
    uiwait(errordlg('Error accessing the photometer, please check the device...', 'Error', 'modal'));
    PR650=[];
end

try
    d = loadDisplayParams('hdr1');
    d.screenNumber = 0;
    d = openScreen(d);

    [lcdIND ledIND] = meshgrid(lcdLevels,ledLevels);

    lcdCtrlBlank = ones(1024,1280,3);
    for(ii=[1:3])
        lcdCtrlBlank(:,:,ii) = lcdCtrlBlank(:,:,ii)*rgb(ii);
    end

    ledCenter = [8 23];
    [ledCtrlX ledCtrlY] = meshgrid( ledCenter(1)-patchSize(1):ledCenter(1)+patchSize(1), ...
        ledCenter(2)-patchSize(2):ledCenter(2)+patchSize(2) );
    ledCtrlBlank = zeros(46,17);

    rand('state',sum(100*clock));
    [randLcdIND randOrder] = Shuffle(lcdIND(:));
    randLedIND = ledIND(:);
    randLedIND = randLedIND(randOrder);
    XYZ = zeros(length(lcdIND(:)),3)*nan;

    getclicks;
   % pause(30);
    
    for(ii=[1:length(lcdIND(:))])

        lcdCtrl = lcdCtrlBlank;
        ledCtrl = ledCtrlBlank;

        cLcdLevel = randLcdIND(ii);
        cLedLevel = randLedIND(ii);

        lcdCtrl = lcdCtrl * cLcdLevel;
        ledCtrl(ledCtrlY,ledCtrlX) = cLedLevel;

        hdrPutImage(d,lcdCtrl,ledCtrl);

        pause(0.25);
        XYZ(ii,1:3) = getdata(PR650, 'xyz');

    end
    
    % When you are done with your measurements, be sure to exit gracefully
    Screen('CloseAll');
    delete(PR650);
    
    inputs = [randLcdIND(:) randLedIND(:)];
    save(['hdrCal',num2str(datenum(now)),'.mat'],'rgb','patchSize','inputs','XYZ');
catch
    % Close window in case of error.
    Screen('CloseAll');

    % Also close the PR650
    delete(PR650);
    rethrow(lasterror);
end
toc