Gamma Table bug

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is read back correctly by ReadNormalizedGammaTable. However, the
% resulting luminances are wrong. And there are different errors on
% different Macs (tested on MacBook Air and MacBook Pro.) This demo
% displays the 9 CLUT entries all at once as an image, nominally a
% luminance ramp, in the upper left. The gamma values appear below, and are
% also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0]
% One of the CLUT entries is displayed as a square in the middle of the
% screen, for photometry. Each time you hit the shift key it advances to
% the next. A numerical display tells you the gamma value displayed. The
% displayed luminances are wrong, as explained below, but
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% UPDATE: Before filing this bug report, I ran UpdatePsychtoolbox on both
% machines. They were already up to date, so the Psychtoolbox version
% didn't change. Even so, to be sure of running the latest I ran
% DownloadPsychtoolbox. Amazingly, this fixed the MacBook Air, but the
% MacBook Pro is still failing.
%
% On my MacBookPro, the darker part of the ramp looks ok, but the nominally
% full white, 1.0, on the right, is less bright than the gray that precedes
% it. On my MacBook Air (before the cure) the nominally black patch (0.0)
% was white, and all the nominally gray and white patches appeared black.
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.13
% I just ran UpdatePsychtoolbox (and then DownloadPsychtoolbox!) on both
% computers, but the versions still differ:
% 3.0.14 - Flavor: beta - Corresponds to SVN Revision 5452
% 3.0.13 - Flavor: beta - Corresponds to SVN Revision 8319
% I don't understand why the 3.0.13 won't upgrade to 3.0.14. I tried
% downloading Psychtoolbox again on both computers, deleting the old
% installation, but I still end up with 3.0.13 on the Air and 3.0.14 on the
% Pro. Weird.
%
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% my code runs the same, with or without EnableCLUTMapping.
%
% Denis Pelli February 22, 2017
try
Screen('Preference', 'SkipSyncTests', 1);
screen=0;
AutoBrightness(screen,0);
Screen('ConfigureDisplay','Brightness',screen,[],1);
if 1
PsychImaging('PrepareConfiguration');
PsychImaging('AddTask','General','UseRetinaResolution');
% Mario says EnableCLUTMapping is the ONLY way to get reasonable
% color mapping behavior.
PsychImaging('AddTask','AllViews','EnableCLUTMapping',256,1); % clutSize, high res
[window,screenRect]=PsychImaging('OpenWindow',screen,255);
else
[window,screenRect]=Screen('OpenWindow',screen,255,[],[],[],[],[],kPsychNeedRetinaResolution);
end
[gammaLong,dacBits]=Screen('ReadNormalizedGammaTable',0);
saveGamma=gammaLong;
gamma=gammaLong(round(1+(size(gammaLong,1)-1)*(0:255)/255),1:3); % scrunch down to 256
gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
gamma(1:9,3)=gamma(1:9,2);
gammaLong=Expand(gamma,1,size(gammaLong,1)/size(gamma,1)); % Match length of gamma table that we read.
Screen('LoadNormalizedGammaTable',0,gammaLong);
Screen('TextSize',window,40);
for i=1:9
rect=CenterRect(screenRect/4,screenRect);
Screen('FillRect',window,128,screenRect);
Screen('PutImage',window,0:8,[0 0 200 50]);
Screen('DrawText',window,sprintf('%.3f ',gamma(1:9,2)),40,100);
Screen('FillRect',window,i-1,rect);
Screen('DrawText',window,sprintf('gamma(%d)=%.3f',i,gamma(i,2)),40,200);
Screen('DrawText',window,'Hit <shift> to continue.',40,300);
Screen('Flip', window);
KbStrokeWait();
Beeper();
end
Screen('CloseAll');
[newGammaLong,dacBits]=Screen('ReadNormalizedGammaTable',0);
newGamma=newGammaLong(round(1+(size(newGammaLong,1)-1)*(0:255)/255),1:3); % scrunch down to 256
fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
for i=1:9
fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2),newGamma(i,2));
end
fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
for i=1:9*4
fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2),newGammaLong(i,2));
end
Screen('LoadNormalizedGammaTable',0,saveGamma);
catch
sca;
Screen('LoadNormalizedGammaTable',0,saveGamma);
psychrethrow(psychlasterror);
end

photo
Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com
Correction: Psychtoolbox on both computers are now at version 3.0.14. I'm not sure how I misread the version. I corrected my message below, and the notes in my program.


On Wed, Feb 22, 2017 at 10:55 PM, Denis Pelli denis.pelli@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
[Attachment(s) from Denis Pelli included below]

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is always read back correctly by ReadNormalizedGammaTable.
% However, the resulting luminances are wrong on my MacBook Pro, even
% though they are correct on my MacBook Air. This demo displays the 9 CLUT
% entries all at once as an image, nominally a luminance ramp, in the upper
% left. The gamma values appear below, and are also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0] One of the CLUT
% entries is displayed as a square in the middle of the screen, for
% photometry. Each time you hit the shift key it advances to the next. A
% numerical display tells you the gamma value displayed. The displayed
% luminances are wrong, as explained below, even though
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% On my MacBookPro​ (running PTB 3.0.14)​, the darker part of the ramp
% looks ok, but the nominally full white, 1.0, on the right, is less bright
% than the gray that precedes it. In now runs fine on my MacBook Air, now
% running PTB 3.0.14. However, ​while running PTB 3.0.13, the MacBook Air
% displayed the nominally black patch (0.0) as white, and all the
% nominally gray and white patches appeared black.​
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
%
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% I have the same problem, with or without EnableCLUTMapping.
%
% Denis Pelli February 22, 2017
try
Screen('Preference', 'SkipSyncTests', 1);
screen=0;
AutoBrightness(screen,0);
Screen('ConfigureDisplay','Brightness',screen,[],1);
if 1
PsychImaging('PrepareConfiguration');
PsychImaging('AddTask','General','UseRetinaResolution');
% Mario says EnableCLUTMapping is the ONLY way to get reasonable
% color mapping behavior.
PsychImaging('AddTask','AllViews','EnableCLUTMapping',256,1); % clutSize, high res
[window,screenRect]=PsychImaging('OpenWindow',screen,255);
else
[window,screenRect]=Screen('OpenWindow',screen,255,[],[],[],[],[],kPsychNeedRetinaResolution);
end
[gammaLong,dacBits]=Screen('ReadNormalizedGammaTable',0);
saveGamma=gammaLong;
gamma=gammaLong(round(1+(size(gammaLong,1)-1)*(0:255)/255),1:3); % scrunch down to 256
gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
gamma(1:9,3)=gamma(1:9,2);
gammaLong=Expand(gamma,1,size(gammaLong,1)/size(gamma,1)); % Match length of gamma table that we read.
Screen('LoadNormalizedGammaTable',0,gammaLong);
Screen('TextSize',window,40);
for i=1:9
rect=CenterRect(screenRect/4,screenRect);
Screen('FillRect',window,128,screenRect);
Screen('PutImage',window,0:8,[0 0 200 50]);
Screen('DrawText',window,sprintf('%.3f ',gamma(1:9,2)),40,100);
Screen('FillRect',window,i-1,rect);
Screen('DrawText',window,sprintf('gamma(%d)=%.3f',i,gamma(i,2)),40,200);
Screen('DrawText',window,'Hit <shift> to continue.',40,300);
Screen('Flip', window);
KbStrokeWait();
Beeper();
end
Screen('CloseAll');
[newGammaLong,dacBits]=Screen('ReadNormalizedGammaTable',0);
newGamma=newGammaLong(round(1+(size(newGammaLong,1)-1)*(0:255)/255),1:3); % scrunch down to 256
fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
for i=1:9
fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2),newGamma(i,2));
end
fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
for i=1:9*4
fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2),newGammaLong(i,2));
end
Screen('LoadNormalizedGammaTable',0,saveGamma);
catch
sca;
Screen('LoadNormalizedGammaTable',0,saveGamma);
psychrethrow(psychlasterror);
end

Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com


Dear Mario
I figured out what's wrong. The sequence of luminances displayed on my MacBook Pro 15" is smoother than the values I loaded into the CLUT. The white (1.0) that I requested was coming out darker because the subsequent values in the lookup table are darker. When I replace the neighboring CLUT elements with white, then I get a good white. I suppose an Apple or AMD engineer thought it would be helpful to smooth the CLUT. (The error is not visible to ReadNormalizedGammaTable.) Can we prevent that?
Best
Denis


Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com

On Wed, Feb 22, 2017 at 11:14 PM, Denis Pelli <denis.pelli@...> wrote:
Correction: Psychtoolbox on both computers are now at version 3.0.14. I'm not sure how I misread the version. I corrected my message below, and the notes in my program.


On Wed, Feb 22, 2017 at 10:55 PM, Denis Pelli denis.pelli@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
[Attachment(s) from Denis Pelli included below]

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is always read back correctly by ReadNormalizedGammaTable.
% However, the resulting luminances are wrong on my MacBook Pro, even
% though they are correct on my MacBook Air. This demo displays the 9 CLUT
% entries all at once as an image, nominally a luminance ramp, in the upper
% left. The gamma values appear below, and are also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0] One of the CLUT
% entries is displayed as a square in the middle of the screen, for
% photometry. Each time you hit the shift key it advances to the next. A
% numerical display tells you the gamma value displayed. The displayed
% luminances are wrong, as explained below, even though
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% On my MacBookPro​ (running PTB 3.0.14)​, the darker part of the ramp
% looks ok, but the nominally full white, 1.0, on the right, is less bright
% than the gray that precedes it. In now runs fine on my MacBook Air, now
% running PTB 3.0.14. However, ​while running PTB 3.0.13, the MacBook Air
% displayed the nominally black patch (0.0) as white, and all the
% nominally gray and white patches appeared black.​
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
%
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% I have the same problem, with or without EnableCLUTMapping.
%
% Denis Pelli February 22, 2017
try
Screen('Preference', 'SkipSyncTests', 1);
screen=0;
AutoBrightness(screen,0);
Screen('ConfigureDisplay',' Brightness',screen,[],1);
if 1
PsychImaging(' PrepareConfiguration');
PsychImaging('AddTask',' General','UseRetinaResolution' );
% Mario says EnableCLUTMapping is the ONLY way to get reasonable
% color mapping behavior.
PsychImaging('AddTask',' AllViews','EnableCLUTMapping', 256,1); % clutSize, high res
[window,screenRect]= PsychImaging('OpenWindow', screen,255);
else
[window,screenRect]=Screen(' OpenWindow',screen,255,[],[],[ ],[],[], kPsychNeedRetinaResolution);
end
[gammaLong,dacBits]=Screen(' ReadNormalizedGammaTable',0);
saveGamma=gammaLong;
gamma=gammaLong(round(1+( size(gammaLong,1)-1)*(0:255)/ 255),1:3); % scrunch down to 256
gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
gamma(1:9,3)=gamma(1:9,2);
gammaLong=Expand(gamma,1, size(gammaLong,1)/size(gamma, 1)); % Match length of gamma table that we read.
Screen(' LoadNormalizedGammaTable',0, gammaLong);
Screen('TextSize',window,40);
for i=1:9
rect=CenterRect(screenRect/4, screenRect);
Screen('FillRect',window,128, screenRect);
Screen('PutImage',window,0:8,[ 0 0 200 50]);
Screen('DrawText',window, sprintf('%.3f ',gamma(1:9,2)),40,100);
Screen('FillRect',window,i-1, rect);
Screen('DrawText',window, sprintf('gamma(%d)=%.3f',i, gamma(i,2)),40,200);
Screen('DrawText',window,'Hit <shift> to continue.',40,300);
Screen('Flip', window);
KbStrokeWait();
Beeper();
end
Screen('CloseAll');
[newGammaLong,dacBits]= Screen(' ReadNormalizedGammaTable',0);
newGamma=newGammaLong(round( 1+(size(newGammaLong,1)-1)*(0: 255)/255),1:3); % scrunch down to 256
fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
for i=1:9
fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2), newGamma(i,2));
end
fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
for i=1:9*4
fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2), newGammaLong(i,2));
end
Screen(' LoadNormalizedGammaTable',0, saveGamma);
catch
sca;
Screen(' LoadNormalizedGammaTable',0, saveGamma);
psychrethrow(psychlasterror);
end

Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com



Sounds like a DESIGN that Apple would love.

Best,
Hörmet
----
Hörmet Yiltiz (
Yuermaitijiang Yilitizi)
Department of Psychology, New York University
6 Washington Place, NY, NY, 10003
hyiltiz@... (Personal)
862-801-2358

On Wed, Feb 22, 2017 at 11:41 PM, Denis Pelli <denis.pelli@...> wrote:
Dear Mario
I figured out what's wrong. The sequence of luminances displayed on my MacBook Pro 15" is smoother than the values I loaded into the CLUT. The white (1.0) that I requested was coming out darker because the subsequent values in the lookup table are darker. When I replace the neighboring CLUT elements with white, then I get a good white. I suppose an Apple or AMD engineer thought it would be helpful to smooth the CLUT. (The error is not visible to ReadNormalizedGammaTable.) Can we prevent that?
Best
Denis


Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com

On Wed, Feb 22, 2017 at 11:14 PM, Denis Pelli <denis.pelli@...> wrote:
Correction: Psychtoolbox on both computers are now at version 3.0.14. I'm not sure how I misread the version. I corrected my message below, and the notes in my program.


On Wed, Feb 22, 2017 at 10:55 PM, Denis Pelli denis.pelli@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
[Attachment(s) from Denis Pelli included below]

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is always read back correctly by ReadNormalizedGammaTable.
% However, the resulting luminances are wrong on my MacBook Pro, even
% though they are correct on my MacBook Air. This demo displays the 9 CLUT
% entries all at once as an image, nominally a luminance ramp, in the upper
% left. The gamma values appear below, and are also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0] One of the CLUT
% entries is displayed as a square in the middle of the screen, for
% photometry. Each time you hit the shift key it advances to the next. A
% numerical display tells you the gamma value displayed. The displayed
% luminances are wrong, as explained below, even though
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% On my MacBookPro​ (running PTB 3.0.14)​, the darker part of the ramp
% looks ok, but the nominally full white, 1.0, on the right, is less bright
% than the gray that precedes it. In now runs fine on my MacBook Air, now
% running PTB 3.0.14. However, ​while running PTB 3.0.13, the MacBook Air
% displayed the nominally black patch (0.0) as white, and all the
% nominally gray and white patches appeared black.​
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
%
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% I have the same problem, with or without EnableCLUTMapping.
%
% Denis Pelli February 22, 2017
try
Screen('Preference', 'SkipSyncTests', 1);
screen=0;
AutoBrightness(screen,0);
Screen('ConfigureDisplay','Br ightness',screen,[],1);
if 1
PsychImaging('PrepareConfigura tion');
PsychImaging('AddTask','Genera l','UseRetinaResolution');
% Mario says EnableCLUTMapping is the ONLY way to get reasonable
% color mapping behavior.
PsychImaging('AddTask','AllVie ws','EnableCLUTMapping',256,1) ; % clutSize, high res
[window,screenRect]=PsychImagi ng('OpenWindow',screen,255);
else
[window,screenRect]=Screen('Op enWindow',screen,255,[],[],[], [],[],kPsychNeedRetinaResoluti on);
end
[gammaLong,dacBits]=Screen('R eadNormalizedGammaTable',0);
saveGamma=gammaLong;
gamma=gammaLong(round(1+(size (gammaLong,1)-1)*(0:255)/255), 1:3); % scrunch down to 256
gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
gamma(1:9,3)=gamma(1:9,2);
gammaLong=Expand(gamma,1,size (gammaLong,1)/size(gamma,1)); % Match length of gamma table that we read.
Screen('LoadNormalizedGammaTa ble',0,gammaLong);
Screen('TextSize',window,40);
for i=1:9
rect=CenterRect(screenRect/4,s creenRect);
Screen('FillRect',window,128,s creenRect);
Screen('PutImage',window,0:8,[ 0 0 200 50]);
Screen('DrawText',window,sprin tf('%.3f ',gamma(1:9,2)),40,100);
Screen('FillRect',window,i-1,r ect);
Screen('DrawText',window,sprin tf('gamma(%d)=%.3f',i,gamma(i, 2)),40,200);
Screen('DrawText',window,'Hit <shift> to continue.',40,300);
Screen('Flip', window);
KbStrokeWait();
Beeper();
end
Screen('CloseAll');
[newGammaLong,dacBits]=Screen ('ReadNormalizedGammaTable',0) ;
newGamma=newGammaLong(round(1 +(size(newGammaLong,1)-1)*(0:2 55)/255),1:3); % scrunch down to 256
fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
for i=1:9
fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2),newGamma (i,2));
end
fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
for i=1:9*4
fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2),newG ammaLong(i,2));
end
Screen('LoadNormalizedGammaTa ble',0,saveGamma);
catch
sca;
Screen('LoadNormalizedGammaTa ble',0,saveGamma);
psychrethrow(psychlasterror);
end

Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com




Hi Denis,

no there isn't anything we could do.

In general it's not a good idea anymore to use gamma tables for anything but gamma correction.

On MS-Windows, gamma tables like yours won't work at all. They get rejected by the OS as invalid if they don't have the general shape of a gamma table.

More recent generations of at least Intel and AMD hardware, possibly NVidia as well, do support a new type of gamma tables in their hardware in addition to old style discrete lookup tables, and it is at the discretion of the display driver (writer) if those new tables are used instead of the old ones.

The new tables often have less slots than the framebuffer has bits per color. E.g., you can have > 8 bpc framebuffers but the hardware tables may only have 256 slots or maybe 512 slots. So the tables no longer store one output value per framebuffer input value, but the slots store, e.g., 256 or 512 reference values. For given framebuffer input color values the hardware interpolates between those reference values, could be piece-wise linear interpolation or something more higher order.

Implementation details between hardware manufacturers and different models from the same manufacturer differ, so the only safe assumption is that you will screw up and/or make your code highly non-portable across operating systems or different computers if you use gamma tables for anything but gamma correction.

This could be an operating system bug for your gpu, or it could simply be that Apples AMD display drivers now have switched to those new interpolated gamma tables.

The only somewhat safe and sane way forward for > 8 bpc precision is to use > 8 bpc framebuffers on suitable hardware.

Linux on AMD hardware would obviously provide that. On a 8 bpc panel it could use 2 bit spatial dithering to simulate 10 bpc. That's what you got so far on your OSX setup by twiddling the 9th and 10 th gamma table bits. On 10 bpc panels via HDMI and DisplayPort it can do native 10 bits, dithered 11 bits and for some special AMD gpu's up to dithered 12 bits if Hormets results check out in the end.

On OSX with AMD hardware you could downgrade to the now unsupported OSX 10.10 + PTB 3.0.13 + PsychtoolboxKernelDriver to get dithered 10 bits on digital displays.

On OSX 10.12 + PTB 3.0.14 with AMD hardware you could give that iMac 5k of yours a try, the one that presumably has a 10 bit panel? Apple claims 10 bit should work on "the late 2014 and late 2015 iMac 27 inch Retina 5k models." Psychtoolbox implements native 10 bit framebuffer mode via the 'EnableNative10BitFramebuffer' task, based on the sparse documentation by Apple. However this is completely untested on real hardware, as none of the people who promised me to test this did.

-mario

XX---In PSYCHTOOLBOX@yahoogroups.com, <denis.pelli@...> wrote :

Dear Mario
I figured out what's wrong. The sequence of luminances displayed on my MacBook Pro 15" is smoother than the values I loaded into the CLUT. The white (1.0) that I requested was coming out darker because the subsequent values in the lookup table are darker. When I replace the neighboring CLUT elements with white, then I get a good white. I suppose an Apple or AMD engineer thought it would be helpful to smooth the CLUT. (The error is not visible to ReadNormalizedGammaTable.) Can we prevent that?
Best
Denis


Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com

On Wed, Feb 22, 2017 at 11:14 PM, Denis Pelli <denis.pelli@...> wrote:
Correction: Psychtoolbox on both computers are now at version 3.0.14. I'm not sure how I misread the version. I corrected my message below, and the notes in my program.


On Wed, Feb 22, 2017 at 10:55 PM, Denis Pelli denis.pelli@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
 
[Attachment(s) from Denis Pelli included below]

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is always read back correctly by ReadNormalizedGammaTable.
% However, the resulting luminances are wrong on my MacBook Pro, even
% though they are correct on my MacBook Air. This demo displays the 9 CLUT
% entries all at once as an image, nominally a luminance ramp, in the upper
% left. The gamma values appear below, and are also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0] One of the CLUT
% entries is displayed as a square in the middle of the screen, for
% photometry. Each time you hit the shift key it advances to the next. A
% numerical display tells you the gamma value displayed. The displayed
% luminances are wrong, as explained below, even though
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% On my MacBookPro​ (running PTB 3.0.14)​, the darker part of the ramp
% looks ok, but the nominally full white, 1.0, on the right, is less bright
% than the gray that precedes it. In now runs fine on my MacBook Air, now
% running PTB 3.0.14. However, ​while running PTB 3.0.13, the MacBook Air
% displayed the nominally black patch (0.0) as white, and all the
% nominally gray and white patches appeared black.​
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% I have the same problem, with or without EnableCLUTMapping.
% Denis Pelli February 22, 2017
try
   Screen('Preference', 'SkipSyncTests', 1);
   screen=0;
   AutoBrightness(screen,0);
   Screen('ConfigureDisplay',' Brightness',screen,[],1);
   if 1
      PsychImaging(' PrepareConfiguration');
      PsychImaging('AddTask',' General','UseRetinaResolution' );
      % Mario says EnableCLUTMapping is the ONLY way to get reasonable
      % color mapping behavior.
      PsychImaging('AddTask',' AllViews','EnableCLUTMapping', 256,1); % clutSize, high res
      [window,screenRect]= PsychImaging('OpenWindow', screen,255);
   else
      [window,screenRect]=Screen(' OpenWindow',screen,255,[],[],[ ],[],[], kPsychNeedRetinaResolution);
   end
   [gammaLong,dacBits]=Screen(' ReadNormalizedGammaTable',0);
   saveGamma=gammaLong;
   gamma=gammaLong(round(1+( size(gammaLong,1)-1)*(0:255)/ 255),1:3); % scrunch down to 256
   gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
   gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
   gamma(1:9,3)=gamma(1:9,2);
   gammaLong=Expand(gamma,1, size(gammaLong,1)/size(gamma, 1)); % Match length of gamma table that we read.
   Screen(' LoadNormalizedGammaTable',0, gammaLong);
   Screen('TextSize',window,40);
   for i=1:9
      rect=CenterRect(screenRect/4, screenRect);
      Screen('FillRect',window,128, screenRect);
      Screen('PutImage',window,0:8,[ 0 0 200 50]);
      Screen('DrawText',window, sprintf('%.3f ',gamma(1:9,2)),40,100);
      Screen('FillRect',window,i-1, rect);
      Screen('DrawText',window, sprintf('gamma(%d)=%.3f',i, gamma(i,2)),40,200);
      Screen('DrawText',window,'Hit <shift> to continue.',40,300);
      Screen('Flip', window);
      KbStrokeWait();
      Beeper();
   end
   Screen('CloseAll');
   [newGammaLong,dacBits]= Screen(' ReadNormalizedGammaTable',0);
   newGamma=newGammaLong(round( 1+(size(newGammaLong,1)-1)*(0: 255)/255),1:3); % scrunch down to 256
   fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
   for i=1:9
      fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2), newGamma(i,2));
   end
   fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
   for i=1:9*4
      fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2), newGammaLong(i,2));
   end
   Screen(' LoadNormalizedGammaTable',0, saveGamma);
catch
   sca;
   Screen(' LoadNormalizedGammaTable',0, saveGamma);
   psychrethrow(psychlasterror);
end

Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com



Dear Mario
Thanks for the long, full, explanation. I agree that Hörmet's success (with your help) in getting 12-bit channels working (on my new linux hp laptop) is terrific. However, that currently requires linux, and for most people, buying a new computer. To measure threshold, I remain very happy to achieve 10+ bit precision from 8-bit channels on many Macs running under macOS, by following your advice to use LoadNormalizedGammaTable with EnableCLUTMapping. To measure contrast threshold, i don't mind setting up the CLUT to use the whole 0:255 range of the pixel to represent only a limited luminance range near the desired mean luminance. Each of the 256 clut entries is specified (as a float) with more than 8 bits. As you note, 8 bits plus dithering performs comparably to 10-bit precision for some purposes. Being limited to only 256 elements in the gamma table is fine when working with 8-bit images. Some computers, like my MacBook Pro 15" achieve more than 11-bit precision.

Going forward, many people will want to follow the lead set by you and Hormet achieving 12-bits per channel on my linux hp laptop. However, for threshold studies, 8-bit channels with high precision gamma tables remain an excellent way to go, and compatible with ordinary macOS computers.

Thanks!
Best
Denis


On Thu, Feb 23, 2017 at 11:56 PM, mario.kleiner@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:

Hi Denis,

no there isn't anything we could do.

In general it's not a good idea anymore to use gamma tables for anything but gamma correction.

On MS-Windows, gamma tables like yours won't work at all. They get rejected by the OS as invalid if they don't have the general shape of a gamma table.

More recent generations of at least Intel and AMD hardware, possibly NVidia as well, do support a new type of gamma tables in their hardware in addition to old style discrete lookup tables, and it is at the discretion of the display driver (writer) if those new tables are used instead of the old ones.

The new tables often have less slots than the framebuffer has bits per color. E.g., you can have > 8 bpc framebuffers but the hardware tables may only have 256 slots or maybe 512 slots. So the tables no longer store one output value per framebuffer input value, but the slots store, e.g., 256 or 512 reference values. For given framebuffer input color values the hardware interpolates between those reference values, could be piece-wise linear interpolation or something more higher order.

Implementation details between hardware manufacturers and different models from the same manufacturer differ, so the only safe assumption is that you will screw up and/or make your code highly non-portable across operating systems or different computers if you use gamma tables for anything but gamma correction.

This could be an operating system bug for your gpu, or it could simply be that Apples AMD display drivers now have switched to those new interpolated gamma tables.

The only somewhat safe and sane way forward for > 8 bpc precision is to use > 8 bpc framebuffers on suitable hardware.

Linux on AMD hardware would obviously provide that. On a 8 bpc panel it could use 2 bit spatial dithering to simulate 10 bpc. That's what you got so far on your OSX setup by twiddling the 9th and 10 th gamma table bits. On 10 bpc panels via HDMI and DisplayPort it can do native 10 bits, dithered 11 bits and for some special AMD gpu's up to dithered 12 bits if Hormets results check out in the end.

On OSX with AMD hardware you could downgrade to the now unsupported OSX 10.10 + PTB 3.0.13 + PsychtoolboxKernelDriver to get dithered 10 bits on digital displays.

On OSX 10.12 + PTB 3.0.14 with AMD hardware you could give that iMac 5k of yours a try, the one that presumably has a 10 bit panel? Apple claims 10 bit should work on "the late 2014 and late 2015 iMac 27 inch Retina 5k models." Psychtoolbox implements native 10 bit framebuffer mode via the 'EnableNative10BitFramebuffer' task, based on the sparse documentation by Apple. However this is completely untested on real hardware, as none of the people who promised me to test this did.

-mario

XX---In PSYCHTOOLBOX@yahoogroups.com, <denis.pelli@...> wrote :

Dear Mario
I figured out what's wrong. The sequence of luminances displayed on my MacBook Pro 15" is smoother than the values I loaded into the CLUT. The white (1.0) that I requested was coming out darker because the subsequent values in the lookup table are darker. When I replace the neighboring CLUT elements with white, then I get a good white. I suppose an Apple or AMD engineer thought it would be helpful to smooth the CLUT. (The error is not visible to ReadNormalizedGammaTable.) Can we prevent that?
Best
Denis


Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com

On Wed, Feb 22, 2017 at 11:14 PM, Denis Pelli <denis.pelli@...> wrote:
Correction: Psychtoolbox on both computers are now at version 3.0.14. I'm not sure how I misread the version. I corrected my message below, and the notes in my program.


On Wed, Feb 22, 2017 at 10:55 PM, Denis Pelli denis.pelli@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
[Attachment(s) from Denis Pelli included below]

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is always read back correctly by ReadNormalizedGammaTable.
% However, the resulting luminances are wrong on my MacBook Pro, even
% though they are correct on my MacBook Air. This demo displays the 9 CLUT
% entries all at once as an image, nominally a luminance ramp, in the upper
% left. The gamma values appear below, and are also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0] One of the CLUT
% entries is displayed as a square in the middle of the screen, for
% photometry. Each time you hit the shift key it advances to the next. A
% numerical display tells you the gamma value displayed. The displayed
% luminances are wrong, as explained below, even though
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% On my MacBookPro​ (running PTB 3.0.14)​, the darker part of the ramp
% looks ok, but the nominally full white, 1.0, on the right, is less bright
% than the gray that precedes it. In now runs fine on my MacBook Air, now
% running PTB 3.0.14. However, ​while running PTB 3.0.13, the MacBook Air
% displayed the nominally black patch (0.0) as white, and all the
% nominally gray and white patches appeared black.​
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
%
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% I have the same problem, with or without EnableCLUTMapping.
%
% Denis Pelli February 22, 2017
try
Screen('Preference', 'SkipSyncTests', 1);
screen=0;
AutoBrightness(screen,0);
Screen('ConfigureDisplay',' Brightness',screen,[],1);
if 1
PsychImaging(' PrepareConfiguration');
PsychImaging('AddTask',' General','UseRetinaResolution' );
% Mario says EnableCLUTMapping is the ONLY way to get reasonable
% color mapping behavior.
PsychImaging('AddTask',' AllViews','EnableCLUTMapping', 256,1); % clutSize, high res
[window,screenRect]= PsychImaging('OpenWindow', screen,255);
else
[window,screenRect]=Screen(' OpenWindow',screen,255,[],[],[ ],[],[], kPsychNeedRetinaResolution);
end
[gammaLong,dacBits]=Screen(' ReadNormalizedGammaTable',0);
saveGamma=gammaLong;
gamma=gammaLong(round(1+( size(gammaLong,1)-1)*(0:255)/ 255),1:3); % scrunch down to 256
gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
gamma(1:9,3)=gamma(1:9,2);
gammaLong=Expand(gamma,1, size(gammaLong,1)/size(gamma, 1)); % Match length of gamma table that we read.
Screen(' LoadNormalizedGammaTable',0, gammaLong);
Screen('TextSize',window,40);
for i=1:9
rect=CenterRect(screenRect/4, screenRect);
Screen('FillRect',window,128, screenRect);
Screen('PutImage',window,0:8,[ 0 0 200 50]);
Screen('DrawText',window, sprintf('%.3f ',gamma(1:9,2)),40,100);
Screen('FillRect',window,i-1, rect);
Screen('DrawText',window, sprintf('gamma(%d)=%.3f',i, gamma(i,2)),40,200);
Screen('DrawText',window,'Hit <shift> to continue.',40,300);
Screen('Flip', window);
KbStrokeWait();
Beeper();
end
Screen('CloseAll');
[newGammaLong,dacBits]= Screen(' ReadNormalizedGammaTable',0);
newGamma=newGammaLong(round( 1+(size(newGammaLong,1)-1)*(0: 255)/255),1:3); % scrunch down to 256
fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
for i=1:9
fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2), newGamma(i,2));
end
fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
for i=1:9*4
fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2), newGammaLong(i,2));
end
Screen(' LoadNormalizedGammaTable',0, saveGamma);
catch
sca;
Screen(' LoadNormalizedGammaTable',0, saveGamma);
psychrethrow(psychlasterror);
end

Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com




XX---In PSYCHTOOLBOX@yahoogroups.com, <denis.pelli@...> wrote :

Dear Mario
Thanks for the long, full, explanation. I agree that Hörmet's success (with your help) in getting 12-bit channels working (on my new linux hp laptop) is terrific. However, that currently requires linux, and for most people, buying a new computer. To measure threshold, I remain very happy to achieve 10+ bit precision from 8-bit channels on many Macs running under macOS, by following your advice to use LoadNormalizedGammaTable with EnableCLUTMapping. To measure

-> EnableCLUTMapping won't help there? It's useful for remapping pixel color indices to colors, and especially/mostly for CLUT animation, but i'm not sure how it would help here?


contrast threshold, i don't mind setting up the CLUT to use the whole 0:255 range of the pixel to represent only a limited luminance range near the desired mean luminance. Each of the 256 clut entries is specified (as a float) with more than 8 bits. As you note, 8 bits plus dithering performs comparably to 10-bit precision for some purposes. Being limited to only 256 elements in the gamma table is fine when working with 8-bit images.

-> Sure that might work if you don't need entries for something else like instructions. On Windows that might fail as well.

Some computers, like my MacBook Pro 15" achieve more than 11-bit precision. 

-> I doubt you'd get more than 10 bits via dithering, given that all Mac laptop panels are at most 8 bpc, older ones even only 6 bpc? At least last time i checked, gpu's couldn't add more than 2 bits. What Mac model, graphics card and display is this?

-mario

Going forward, many people will want to follow the lead set by you and Hormet achieving 12-bits per channel on my linux hp laptop. However, for threshold studies,  8-bit channels with high precision gamma tables remain an excellent way to go, and compatible with ordinary macOS computers.

Thanks!
Best
Denis


On Thu, Feb 23, 2017 at 11:56 PM, mario.kleiner@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
 

Hi Denis,

no there isn't anything we could do.

In general it's not a good idea anymore to use gamma tables for anything but gamma correction.

On MS-Windows, gamma tables like yours won't work at all. They get rejected by the OS as invalid if they don't have the general shape of a gamma table.

More recent generations of at least Intel and AMD hardware, possibly NVidia as well, do support a new type of gamma tables in their hardware in addition to old style discrete lookup tables, and it is at the discretion of the display driver (writer) if those new tables are used instead of the old ones.

The new tables often have less slots than the framebuffer has bits per color. E.g., you can have > 8 bpc framebuffers but the hardware tables may only have 256 slots or maybe 512 slots. So the tables no longer store one output value per framebuffer input value, but the slots store, e.g., 256 or 512 reference values. For given framebuffer input color values the hardware interpolates between those reference values, could be piece-wise linear interpolation or something more higher order.

Implementation details between hardware manufacturers and different models from the same manufacturer differ, so the only safe assumption is that you will screw up and/or make your code highly non-portable across operating systems or different computers if you use gamma tables for anything but gamma correction.

This could be an operating system bug for your gpu, or it could simply be that Apples AMD display drivers now have switched to those new interpolated gamma tables.

The only somewhat safe and sane way forward for > 8 bpc precision is to use > 8 bpc framebuffers on suitable hardware.

Linux on AMD hardware would obviously provide that. On a 8 bpc panel it could use 2 bit spatial dithering to simulate 10 bpc. That's what you got so far on your OSX setup by twiddling the 9th and 10 th gamma table bits. On 10 bpc panels via HDMI and DisplayPort it can do native 10 bits, dithered 11 bits and for some special AMD gpu's up to dithered 12 bits if Hormets results check out in the end.

On OSX with AMD hardware you could downgrade to the now unsupported OSX 10.10 + PTB 3.0.13 + PsychtoolboxKernelDriver to get dithered 10 bits on digital displays.

On OSX 10.12 + PTB 3.0.14 with AMD hardware you could give that iMac 5k of yours a try, the one that presumably has a 10 bit panel? Apple claims 10 bit should work on "the late 2014 and late 2015 iMac 27 inch Retina 5k models." Psychtoolbox implements native 10 bit framebuffer mode via the 'EnableNative10BitFramebuffer' task, based on the sparse documentation by Apple. However this is completely untested on real hardware, as none of the people who promised me to test this did.

-mario

XX---In PSYCHTOOLBOX@yahoogroups.com, <denis.pelli@...> wrote :

Dear Mario
I figured out what's wrong. The sequence of luminances displayed on my MacBook Pro 15" is smoother than the values I loaded into the CLUT. The white (1.0) that I requested was coming out darker because the subsequent values in the lookup table are darker. When I replace the neighboring CLUT elements with white, then I get a good white. I suppose an Apple or AMD engineer thought it would be helpful to smooth the CLUT. (The error is not visible to ReadNormalizedGammaTable.) Can we prevent that?
Best
Denis


Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com

On Wed, Feb 22, 2017 at 11:14 PM, Denis Pelli <denis.pelli@...> wrote:
Correction: Psychtoolbox on both computers are now at version 3.0.14. I'm not sure how I misread the version. I corrected my message below, and the notes in my program.


On Wed, Feb 22, 2017 at 10:55 PM, Denis Pelli denis.pelli@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:
 
[Attachment(s) from Denis Pelli included below]

Dear Mario
Can you help? My experiments control contrast by loading the gamma table. ReadNormalizedGammaTable correctly reads back what I loaded using LoadNormalizedGammaTable. On my MacBook Air, since updating Psychtoolbox, I get the right luminances. On my MacBook Pro a nominal luminance ramp produces a non monotonic luminance display. I'm attaching (and pasting below) a short program that exhibits the bug.

I need to fix this urgently to collect data. Any advice?
Best
Denis

% function GammaTableBug()
% Loads a ramp into the first 9 elements of the CLUT using
% LoadNormalizedGammaTable. The ramp goes from black (0.0) to white (1.0).
% The ramp is always read back correctly by ReadNormalizedGammaTable.
% However, the resulting luminances are wrong on my MacBook Pro, even
% though they are correct on my MacBook Air. This demo displays the 9 CLUT
% entries all at once as an image, nominally a luminance ramp, in the upper
% left. The gamma values appear below, and are also printed on the screen.
% [0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0] One of the CLUT
% entries is displayed as a square in the middle of the screen, for
% photometry. Each time you hit the shift key it advances to the next. A
% numerical display tells you the gamma value displayed. The displayed
% luminances are wrong, as explained below, even though
% ReadNormalizedGammaTable always returns exactly what I loaded.
%
% On my MacBookPro​ (running PTB 3.0.14)​, the darker part of the ramp
% looks ok, but the nominally full white, 1.0, on the right, is less bright
% than the gray that precedes it. In now runs fine on my MacBook Air, now
% running PTB 3.0.14. However, ​while running PTB 3.0.13, the MacBook Air
% displayed the nominally black patch (0.0) as white, and all the
% nominally gray and white patches appeared black.​
%
% MacBookPro, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% MacBookAir, macOS 10.12.3, MATLAB 8.6.0 (R2015b), Psychtoolbox 3.0.14
% The last time I wrote to you about CLUT problems, you advised me to use
% EnableCLUTMapping. That helped a lot at the time. However, right now,
% I have the same problem, with or without EnableCLUTMapping.
% Denis Pelli February 22, 2017
try
   Screen('Preference', 'SkipSyncTests', 1);
   screen=0;
   AutoBrightness(screen,0);
   Screen('ConfigureDisplay',' Brightness',screen,[],1);
   if 1
      PsychImaging(' PrepareConfiguration');
      PsychImaging('AddTask',' General','UseRetinaResolution' );
      % Mario says EnableCLUTMapping is the ONLY way to get reasonable
      % color mapping behavior.
      PsychImaging('AddTask',' AllViews','EnableCLUTMapping', 256,1); % clutSize, high res
      [window,screenRect]= PsychImaging('OpenWindow', screen,255);
   else
      [window,screenRect]=Screen(' OpenWindow',screen,255,[],[],[ ],[],[], kPsychNeedRetinaResolution);
   end
   [gammaLong,dacBits]=Screen(' ReadNormalizedGammaTable',0);
   saveGamma=gammaLong;
   gamma=gammaLong(round(1+( size(gammaLong,1)-1)*(0:255)/ 255),1:3); % scrunch down to 256
   gamma(1:9,2)=[0 0.6617 0.7001 0.7374 0.7661 .7916 .8137 0.8361 1.0];
   gamma(1:9,1)=gamma(1:9,2); % Copy green channel to red and blue channels.
   gamma(1:9,3)=gamma(1:9,2);
   gammaLong=Expand(gamma,1, size(gammaLong,1)/size(gamma, 1)); % Match length of gamma table that we read.
   Screen(' LoadNormalizedGammaTable',0, gammaLong);
   Screen('TextSize',window,40);
   for i=1:9
      rect=CenterRect(screenRect/4, screenRect);
      Screen('FillRect',window,128, screenRect);
      Screen('PutImage',window,0:8,[ 0 0 200 50]);
      Screen('DrawText',window, sprintf('%.3f ',gamma(1:9,2)),40,100);
      Screen('FillRect',window,i-1, rect);
      Screen('DrawText',window, sprintf('gamma(%d)=%.3f',i, gamma(i,2)),40,200);
      Screen('DrawText',window,'Hit <shift> to continue.',40,300);
      Screen('Flip', window);
      KbStrokeWait();
      Beeper();
   end
   Screen('CloseAll');
   [newGammaLong,dacBits]= Screen(' ReadNormalizedGammaTable',0);
   newGamma=newGammaLong(round( 1+(size(newGammaLong,1)-1)*(0: 255)/255),1:3); % scrunch down to 256
   fprintf('\ndesired vs. actual gamma, scrunched to 256\n');
   for i=1:9
      fprintf('%2d %5.3f %5.3f\n',i,gamma(i,2), newGamma(i,2));
   end
   fprintf('\ndesired vs. actual gamma, full %d\n',size(gammaLong,1));
   for i=1:9*4
      fprintf('%2d %5.3f %5.3f\n',i,gammaLong(i,2), newGammaLong(i,2));
   end
   Screen(' LoadNormalizedGammaTable',0, saveGamma);
catch
   sca;
   Screen(' LoadNormalizedGammaTable',0, saveGamma);
   psychrethrow(psychlasterror);
end

Denis Pelli
Professor of Psychology & Neural Science, New York University
+1-646-258-7524 | denis.pelli@... | http://psych.nyu.edu/pelli/ | Skype: denispelli | http://denispelli.com