% SimpleCalDemo
%
% Little example that puts up a calibrated series of
% luminance stimuli of desired chromaticity.
%
% Other examples to look at:
%
% ZonePlateDemo, RenderDemo, ContrastThreshDemo
%
% 12/15/99  dhb,awi  Wrote it.
% 11/17/00  dgp      fixed cosmetic typo.
% 4/11/02		awi      replaced DeviceToLinear call with PrimaryToSensor call.
% 4/13/02		awi      replaced SetColorSpace with new name SetSensorColorSpace
% 4/24/02   dgp      Made the Ask message easier to read and understand.

% Parameters
whichScreen = 0;
CONVERT_CAL = 0;

% Define color space that we want
% to work in.  Here it's CIE XYZ,
% but we can specify by any color
% matching functions we like.
% Many options are available in
% PsychColorimetricData.  See
% help for that folder.
load T_xyz1931
T = 683*T_xyz1931;
S = S_xyz1931;

% Load calibration information.
cal = LoadCalFile(whichScreen);

% Rewrite cal structure to contain only
% information we could get with a colorimeter.
if (CONVERT_CAL == 1)
	% Compute the XYZ measurements we would
	% have obtained from the spectral measurements
	% we've got.  Here we're assuming that the
	% calbration file in fact contains spectral
	% data, which is not in principle always true.
	P_deviceXYZ = T_xyz1931*cal.P_device;
	P_ambientXYZ = T_xyz1931*cal.P_ambient;
	
	% Rewrite calibration structure with XYZ
	% data.  Update T_ fields so the structure
	% contains correct information about what is
	% stored for primaries and ambient.
	cal.P_device = P_deviceXYZ;
	cal.T_device = T_xyz1931;
	cal.P_ambient = P_ambientXYZ;
	cal.T_ambient = T_xyz1931;
elseif (CONVERT_CAL == 2)
	% Compute the Y measurements we would
	% have obtained from the spectral measurements
	% we've got.  Here we're assuming that the
	% calbration file in fact contains spectral
	% data, which is not in principle always true.
	%
	% This is a degenerate case that you would
	% want to think about hard before actually
	% using.
	P_deviceY = T_xyz1931(2,:)*cal.P_device;
	P_ambientY= T_xyz1931(2,:)*cal.P_ambient;
	
	% Rewrite calibration structure with XYZ
	% data.  Update T_ fields so the structure
	% contains correct information about what is
	% stored for primaries and ambient.
	cal.P_device = P_deviceY;
	cal.T_device = T_xyz1931(2,:);
	cal.P_ambient = P_ambientY;
	cal.T_ambient = T_xyz1931(2,:);
end

% Initialize calibration structure.
cal = SetGammaMethod(cal,0);
cal = SetSensorColorSpace(cal,T,S);

% Specify desired chromaticity
thexy = [0.4 0.4]';

% Find maximum device luminance so
% we avoid gamut problems.  Then set
% up a range of luminances that are
% probably within device gamut.
maxXYZ = PrimaryToSensor(cal,[1 1 1]');
maxLum = maxXYZ(2);
theLums = linspace(maxLum/10,maxLum/2,5);

% Now display a stimulus at each luminance
% in turn.
[w,rect] = Screen(whichScreen,'OpenWindow',BlackIndex(whichScreen),[],32);
squareRect = CenterRect([0 0 100 100],rect);
theColorImage = zeros(1,1,3);
Screen(w,'SetClut',(0:255)'*ones(1,3));
for i = 1:length(theLums)
	thexyY = [thexy ; theLums(i)];
	theXYZ = xyYToXYZ(thexyY);
	[theSettings,badIndex] = SensorToSettings(cal,theXYZ);
	fprintf('Luminance %g of %g: %g\n',i,length(theLums),theLums(i));
	fprintf('RGB is %g, %g, %g\n',theSettings(1),theSettings(2),theSettings(3));
	if (badIndex)
		fprintf('Warning: desired luminance %g was out of gamut\n',theLums(i));
	end
	fprintf('\n');
	theColorImage(1,1,:) = theSettings;
	Screen(w,'PutImage',theColorImage,squareRect);
	Screen(w,'TextSize',36);
	Screen(w,'TextFont','Arial');
	Ask(w,sprintf('Luminance %g of %g. Click to continue.',i,length(theLums)),WhiteIndex(w),BlackIndex(w));
end

Screen(w,'Close');
