Skip to content

Commit 210c08e

Browse files
committed
Tuning up analysis
1 parent 24f9c38 commit 210c08e

File tree

1 file changed

+63
-49
lines changed

1 file changed

+63
-49
lines changed

code/analysis/monitorGamutInLSPlane/makeMonitorGamutFigure.m

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
case 'detection'
1919
whichCalFile = 'ViewSonicG220fb_670.mat';
2020
whichCalNumber = 4;
21-
nDeviceBits = 12;
21+
nDeviceBits = 18;
2222
whichCones = 'asano';
2323
NOAMBIENT = true;
2424
case 'detectionRaw'
@@ -41,15 +41,18 @@
4141
CalibrateFitGamma(calObjCones, nDeviceLevels);
4242
nPrimaries = calObjCones.get('nDevices');
4343

44-
% Can change gammaMethod to 1 for unquantized analysis
45-
gammaMethod = 2;
46-
SetGammaMethod(calObjCones,gammaMethod);
47-
SetGammaMethod(calObjCones1,gammaMethod);
44+
% Set gamma mode. A value of 2 was used in the experiment
45+
% gammaMode == 0 - search table using linear interpolation via interp1.
46+
% gammaMode == 1 - inverse table lookup. Fast but less accurate.
47+
% gammaMode == 2 - exhaustive search
48+
gammaMode = 2;
49+
SetGammaMethod(calObjCones,gammaMode);
50+
SetGammaMethod(calObjCones1,gammaMode);
4851

4952
% Set wavelength support.
5053
Scolor = calObjCones.get('S');
5154

52-
% Zero out ambient?
55+
% Zero out ambient? We don't zero out the 1 version of the cal object.
5356
if (NOAMBIENT)
5457
calObjCones.set('P_ambient',zeros(size(calObjCones.get('P_ambient'))));
5558
end
@@ -82,8 +85,8 @@
8285

8386
% Get gamma correct
8487
CalibrateFitGamma(calObjXYZ, nDeviceLevels);
85-
SetGammaMethod(calObjXYZ,gammaMethod);
86-
SetGammaMethod(calObjXYZ1,gammaMethod);
88+
SetGammaMethod(calObjXYZ,gammaMode);
89+
SetGammaMethod(calObjXYZ1,gammaMode);
8790
if (NOAMBIENT)
8891
calObjXYZ.set('P_ambient',zeros(size(calObjCones.get('P_ambient'))));
8992
end
@@ -96,10 +99,12 @@
9699
% found it by stepping through the tracking code, and 0.9608 as we found
97100
% it by looking at S.stmLE in the detection code saved data. We divide
98101
% our maximum gamut contrasts by this to get the real maximum contrast we
99-
% report. Not sure why there is a difference.
102+
% report. The difference is that the 0.9221 is the contrast number, while
103+
% the stimulus value represents excitations. We care about contrast for
104+
% this purpose.
100105
imageScaleFactor = 0.9221; % 0.9221; 0.9608;
101106

102-
% XYZ
107+
%% XYZ
103108
USE1931XYZ = true;
104109
if (USE1931XYZ)
105110
load T_xyz1931.mat
@@ -113,11 +118,17 @@
113118

114119
%% Compute ambient
115120
ambientCones = SettingsToSensor(calObjCones,[0 0 0]');
121+
ambientCones1 = SettingsToSensor(calObjCones1,[0 0 0]');
116122
ambientXYZ = SettingsToSensor(calObjXYZ,[0 0 0']');
123+
ambientXYZ1 = SettingsToSensor(calObjXYZ1,[0 0 0']');
117124

118125
%% Compute the background, taking quantization into account
119126
%
120127
% The paper says the background was 30.75 cd/m2, x = 0.326, y = 0.372;
128+
% But, it was alayws set via backround linear rgb = [0.5 0.5 0.5]. THe
129+
% xyY values correspond to specified value.
130+
%
131+
% The calculations here account for display quantization.
121132
SPECIFIEDBG = false;
122133
if (SPECIFIEDBG)
123134
bgxyYTarget = [0.326, 0.372 30.75]';
@@ -141,25 +152,35 @@
141152
fprintf('\nNOAMBIENT = %d, cone option %s\n',NOAMBIENT,whichCones);
142153
fprintf('\nBackground x,y = %0.4f, %0.4f\n',bgxyY(1),bgxyY(2));
143154
fprintf('Background Y = %0.2f cd/m2, ambient %0.3f cd/m2\n',bgXYZ(2),ambientXYZ(2));
155+
fprintf('\nBackground with ambient x,y = %0.4f, %0.4f\n',bgxyY1(1),bgxyY1(2));
156+
fprintf('Background with ambient Y = %0.2f cd/m2, ambient %0.3f cd/m2\n',bgXYZ1(2),ambientXYZ1(2));
144157

145158
% Compute monitor primary xyY to try to understand what drifted
146159
primaryXYZ = PrimaryToSensor(calObjXYZ,[[1 0 0]' [0 1 0]' [0 0 1]']);
147160
primaryxyY = XYZToxyY(primaryXYZ);
161+
primaryXYZ1 = PrimaryToSensor(calObjXYZ1,[[1 0 0]' [0 1 0]' [0 0 1]']);
162+
primaryxyY1 = XYZToxyY(primaryXYZ1);
148163
fprintf('\nRed primary xyY: %0.4f, %0.4f, %0.2f cd/m2\n',primaryxyY(1,1),primaryxyY(2,1),primaryxyY(3,1));
149164
fprintf('Green primary xyY: %0.4f, %0.4f, %0.2f cd/m2\n',primaryxyY(1,2),primaryxyY(2,2),primaryxyY(3,2));
150165
fprintf('Blue primary xyY: %0.4f, %0.4f, %0.2f cd/m2\n',primaryxyY(1,3),primaryxyY(2,3),primaryxyY(3,3));
166+
fprintf('With ambient: Red primary xyY: %0.4f, %0.4f, %0.2f cd/m2\n',primaryxyY1(1,1),primaryxyY1(2,1),primaryxyY1(3,1));
167+
fprintf('With ambient: Green primary xyY: %0.4f, %0.4f, %0.2f cd/m2\n',primaryxyY1(1,2),primaryxyY1(2,2),primaryxyY1(3,2));
168+
fprintf('With ambient: Blue primary xyY: %0.4f, %0.4f, %0.2f cd/m2\n',primaryxyY1(1,3),primaryxyY1(2,3),primaryxyY1(3,3));
151169

152-
% Express background in terms for primaries
170+
% Express background spd in terms of primaries. Not entirely clear this
171+
% means anything important.
153172
bgSpd = cal.processedData.P_ambient;
154173
bgWeights = cal.processedData.P_device\bgSpd;
155174
fprintf('\nAmbient linear rgb weights: %0.3f %0.3f %0.3f\n',bgWeights(1),bgWeights(2),bgWeights(3));
156175
fprintf('\n');
157176

158177
%% Max contrast
159178
%
160-
% Find maximum in gamut contrast for a set of color directions. We
161-
% are not going to worry about device quantization since we used
162-
% high-bit depth hardware
179+
% Find maximum in gamut contrast for a set of color directions.
180+
% This calculation does not worry about quantization. It is
181+
% done for the main case. Because we care about this primarily
182+
% for the tracking experiment, since the experimental specification
183+
% matched what we intended for tha experiment.
163184
nAngles = 1000;
164185
theAngles = linspace(0,2*pi,nAngles);
165186
for aa = 1:nAngles
@@ -198,8 +219,8 @@
198219
% Get the settings that as closely as possible approximate what we
199220
% want. One of these should be very close to 1 or 0, and none should
200221
% be less than 0 or more than 1.
201-
gamutSettings = PrimaryToSettings(calObjCones,gamutPrimaryDir + bgPrimary);
202-
if (any(gamutSettings < 0) | any(gamutSettings > 1))
222+
[gamutSettings,badIndex] = PrimaryToSettings(calObjCones,gamutPrimaryDir + bgPrimary);
223+
if (any(badIndex))
203224
error('Somehow settings got out of gamut\n');
204225
end
205226

@@ -271,8 +292,8 @@
271292
% Get the settings that as closely as possible approximate what we
272293
% want. One of these should be very close to 1 or 0, and none should
273294
% be less than 0 or more than 1.
274-
gamutSettings = PrimaryToSettings(calObjCones,gamutPrimaryDir + bgPrimary);
275-
if (any(gamutSettings < 0) | any(gamutSettings > 1))
295+
[gamutSettings,badIndex] = PrimaryToSettings(calObjCones,gamutPrimaryDir + bgPrimary);
296+
if (any(badIndex))
276297
error('Somehow settings got out of gamut\n');
277298
end
278299

@@ -287,13 +308,21 @@
287308
theSpecificAngles(aa),100*specificGamutContrast(1,aa),100*specificGamutContrast(2,aa),100*specificGamutContrast(3,aa), ...
288309
100*specificVectorLengthContrast(aa));
289310
end
311+
312+
% Look at these variables to get a table of max gamut contrasts in these
313+
% angular directions
290314
specificVectorLengthContrast;
291-
theDetectionSpecificAngles = [0 90.0000 75.0000 -75.0000 45.0000 -45.0000 78.7500 82.5000 86.2000 -78.7500 -82.5000 -86.2000 89.6000 88.6000 87.6000 22.5000 -1.4000 -22.5000];
315+
theSpecificAngles;
292316
clear theSpecficAngles
293317

294318
%% Convert cone contrasts with respect to first calibration to second.
295-
theDetectionSpecificAngles = [-86.25 -82.5 -78.75 -75 -45 0 45 75 78.75 82.5 86.25 90];
296-
theVectorLengthContrasts = [0.05 -0.03 0.02 -75 -45 0 45 75 78.75 82.5 86.25 90];
319+
%
320+
% Angles from paper Figure 5 labels, contrasts read off of those graphs
321+
% roughly by eye. If we go to 16 bit depth, the match would have been very
322+
% good, had the detection calibration been used the way it should have
323+
% been.
324+
theDetectionSpecificAngles = [-86.25 -82.5 -78.75 -75 -45 0 45 75 78.75 82.5 86.25 90];
325+
theVectorLengthContrasts = [ 0.05 0.03 0.02 0.017 0.005 0.003 0.004 0.015 0.02 0.03 0.04 0.05];
297326
for aa = 1:length(theDetectionSpecificAngles)
298327
fprintf('Angle %0.1f, vector length contrast %0.1f\n',theDetectionSpecificAngles(aa),100*theVectorLengthContrasts(aa));
299328

@@ -319,48 +348,34 @@
319348
obtainedCones1(:,aa) = SettingsToSensor(calObjCones1,theSettings);
320349
obtainedConeContrast(:,aa) = ((obtainedCones(:,aa)-bgCones) ./ bgCones);
321350
obtainedConeContrast1(:,aa) = ((obtainedCones1(:,aa)-bgCones1) ./ bgCones1);
351+
obtainedAngle(aa) = atand(obtainedConeContrast(3,aa)/obtainedConeContrast(1,aa));
352+
obtainedAngle1(aa) = atand(obtainedConeContrast1(3,aa)/obtainedConeContrast1(1,aa));
322353
obtainedVectorLength(aa) = norm(obtainedConeContrast(:,aa));
323354
obtainedVectorLength1(aa) = norm(obtainedConeContrast1(:,aa));
355+
angleDeviation(aa) = obtainedAngle1(aa)-obtainedAngle(aa);
356+
vectorLengthDeviation(aa) = obtainedVectorLength1(aa) - obtainedVectorLength(aa);
324357

325358
% Figure out the cone excitations for the settings we computed, and
326359
% then convert to contrast as our maximum contrast in this direction.
327360
%
328361
% Dividing by imageScaleFactor handles the sine phase of the Gabor
329-
fprintf(' Target contrasts: L cone contrast %0.3f%%, M, %0.3f%%, S %0.3f%%, vector length %0.1f%%\n', ...
362+
fprintf(' Target contrasts: L cone contrast %7.3f%%, M, %7.3f%%, S %7.3f%%, angle %7.1f, vector length %0.1f%%\n', ...
330363
100*targetConeContrast(1,aa),100*targetConeContrast(2,aa),100*targetConeContrast(3,aa), ...
331-
100*theVectorLengthContrasts(aa));
332-
fprintf(' Had ambient/cones used been right: L cone contrast %0.3f%%, M, %0.3f%%, S %0.3f%%, vector length %0.1f%%\n', ...
364+
theDetectionSpecificAngles(aa),100*theVectorLengthContrasts(aa));
365+
fprintf(' Had ambient/cones used been right: L cone contrast %7.3f%%, M, %7.3f%%, S %7.3f%%, angle %7.1f, vector length %0.1f%%\n', ...
333366
100*obtainedConeContrast(1,aa),100*obtainedConeContrast(2,aa),100*obtainedConeContrast(3,aa), ...
334-
100*obtainedVectorLength(aa));
335-
fprintf(' What we actually got: L cone contrast %0.3f%%, M, %0.3f%%, S %0.3f%%, vector length %0.1f%%\n', ...
367+
obtainedAngle(aa),100*obtainedVectorLength(aa));
368+
fprintf(' What we actually got: L cone contrast %7.3f%%, M, %7.3f%%, S %7.3f%%, angle %7.1f, vector length %0.1f%%\n', ...
336369
100*obtainedConeContrast1(1,aa),100*obtainedConeContrast1(2,aa),100*obtainedConeContrast1(3,aa), ...
337-
100*obtainedVectorLength1(aa));
370+
obtainedAngle1(aa),100*obtainedVectorLength1(aa));
338371
end
372+
fprintf('\nMax abs angle deviation %0.4f, max abs vector length deviation %0.4f\n',max(abs(angleDeviation)),max(abs(vectorLengthDeviation)));
339373

340-
341-
% CF MAB data from Tracking
374+
%% Gamut chromaticity plot for comparisons
342375
%
343-
% uniqueColorDirs(:)'
344-
%
345-
% ans =
346-
%
347-
% 0 90.0000 75.0000 -75.0000 45.0000 -45.0000 78.7500 82.5000 86.2000 -78.7500 -82.5000 -86.2000 89.6000 88.6000 87.6000 22.5000 -1.4000 -22.5000
348-
%
349-
% matrixContrasts(1,:)
350-
%
351-
% ans =
352-
%
353-
% 0.1800 0.8500 0.6500 0.7800 0.2500 0.2600 0.8300 0.8500 0.8500 0.8400 0.8400 0.8400 0.8500 0.8500 0.8500 0.1900 0.1800 0.1900
354-
%
355-
% cals{1} - August 31 cal, used for tracking experiment
356-
% specificVectorLengthContrast =
357-
%
358-
% 0.1863 0.8513 0.6556 0.7990 0.2569 0.2710 0.8438 0.8734 0.8605 0.8462 0.8442 0.8458 0.8521 0.8542 0.8567 0.1999 0.1865 0.2039
359-
360-
%{
361376
% This code plots the chromaticities from the tracking experiment, the
362377
% detection experiment without the ambient zeroed, and some measurements we
363-
% by hand on 8/2/24.
378+
% by hand on 8/2/24. Numbers here were entered by hand.
364379

365380
% 'tracking'
366381
% Background x,y = 0.3258, 0.3722
@@ -423,4 +438,3 @@
423438
xlabel('x chromaticity');
424439
ylabel('y chromaticity');
425440
xlim([0 1]); ylim([0 1]);
426-
%}

0 commit comments

Comments
 (0)