| Reference | Downloads | Github

Bug with Semi-Auto Gamma Correction

I think I found a bug. (Is this where it should be reported? I am not sure.)
I have encountered slightly different versions of this problem on a MacBook Air using PsychoPy2 v1.90.1 and a Windows Dell using PsychoPy3. On the Mac, I select Monitor Center, Gamma Calibration semi and 8 calibration points. I get 8 calibration screens for Lum, but 7 for R and 7 for green G; but 8 for B. I am measuring with a Minolta spot photometer (no cable) and the 1st value (Black) should be the same for all 4 (lum,R,G,B, right?), but its only the same for lum and B. So the other colors are skipping some value, but I am not sure which.
On the Dell (windows PsychoPy3) the behavior is slightly different. Lum is fine (8 levels), but the others only have 7.
I tried to increase the number of levels to 10 and I get the same result on the Mac: lum and b have 10 values, but r and g only have 9.
I have not put PsychoPy3 on my Mac yet, I want to make sure everything works first. Until you fix this problems I will write my own short script in builder to get 8 values of lum, r, g, & b (and can fill in the form). I tried to look inside PsychoPy to see if I could spot the bug but my programming skills are way not up to it. Maybe some change in np?

Hi Bill,

I have also been experiencing a bug with the semi-auto Gamma Correction, but not the same.
I get 8 values for Lums, 7 for R, G and B, so this is not an issue. I am also using a Minolta spot photometer without cable by the way, but again, this does not change anything.
My problem is that everytime I add the recorded luminances values in the proper table that pops-up at the end of the semi-automatic calibration, the values are not saved at all!
I get the following error message, which I don’t understand unfortunately:

Traceback (most recent call last):			
  File "C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\monitors\", line 835, in onCalibGammaBtn			
    self.onCopyCalib(1)  # create a new dated calibration			
  File "C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\monitors\", line 659, in onCopyCalib			
    caption=_translate('Input text'))			
TypeError: TextEntryDialog(): arguments did not match any overloaded call:			
  overload 1: too many arguments			
  overload 2: 'defaultValue' is not a valid keyword argument			
wx._core.wxAssertionError: C++ assertion "GetEventHandler() == this" failed at ..\..\src\common\wincmn.cpp(478) in wxWindowBase::~wxWindowBase(): any pushed event handlers must have been removed			
The above exception was the direct cause of the following exception:			
SystemError: <class 'wx._core.IdleEvent'> returned a result with an error set			

I have been struggling with this issues for weeks now and cannot figure out how to solve it.
At first I thought it had something to do with the problems with the monitor center and locals on my french computer. But nothing has improved since the recent PsychoPy3 release and it was not working with an english local neither.

Could anyone help?

Many many thanks in advance!

There is a solution to that. You can input the two arrays (RGB number and luminance) in a small script and output the parameters. I have attached the script and printed below.I didn’t go back and test this however. (I didn’t know about semi-automatic and my measurements were not very good.) After using this script (you have to edit in your own values, lines 4 and 6) you should take the measurements again and get a linear function between RGB and cd/m^2. Note that I used 9 values, you want to use 8 I think.* (I was originally using a script from matlab psychoPhysics toolbox it took 9 measurements). It didn’t have a small target area so that is why I thought I really needed a tripod, see below.)

If this works, let me know and send a screen shot of your final table. I started to work on this a long time ago but got distracted. I didn’t know about semi-automatic and the first measurements I didn’t use a tripod. Without a tripod, I am not sure I believe the measurements. (See above, the whole screen was a target.) Maybe. Then I discovered semi-automatic! Then recently I couldn’t get semi-automatic to work! Why I do not know what I am doing wrong.

When I didn’t know about semi-automatic I dug around in the PsychoPy libraries and put together the attached short script. This was a feat because I really do not know much Python, I mostly use builder. I am writing a builder routine that will present the 8 x 4 screen colors, but again got distracted.

Let me know if the attached works! And send me a screen shot if it does. I assume you enter values 0…255 if that is the units you use in your table. Why can’t I get 8 values of Lum, R, G, and B? I will try again. I tried two computers and PsychoPy 2 and 3. Maybe I click too long? I will try it again.

Hello again,
Thanks for the quick response!
I would be very happy to try your script, but I cannot find it :slight_smile:

Here it is, also as an attachment I would use the 8 lum values in the semi-auto script. I could only get it to output the “hard” equation.

This must be done for each color and lum

import psychopy

from psychopy import visual, monitors

inputs=[0,32,64,96,128,160,192,224,255] #Annas input values

#inputs=[0,31,63,95,127,159,191,223,255] # PSYCHOPYS VALUES GIVEN THEIR ‘SEMI’ OPTION

lums=[0.26, 0.35, 0.75, 1.48, 2.55, 4.25, 6.47, 9.13, 10.5 ]

myfit = psychopy.monitors.GammaCalculator(inputs, lums,eq=4)

print “gamma”,myfit.gamma

print “a”,myfit.a

print “b”,myfit.b

print “k”,myfit.k

print “bye”

Hi Bill,

Sorry for the late reply!
I have tried your code and here is what I get. Just had to add a few brackets.

import psychopy

from psychopy import visual, monitors

inputs=[0,36,72,109,145,182,218,255] # PSYCHOPYS VALUES GIVEN THEIR ‘SEMI’ OPTION

lums=[1.23, 1.795, 5.525, 14.0425, 28.6, 49.445, 76.275, 112.35]

myfit = psychopy.monitors.GammaCalculator(inputs, lums,eq=4)


print (“a”,myfit.a)

print (“b”,myfit.b)

print (“k”,myfit.k)

print (“bye”)

Here is what I get:

############## Running: C:\Users\creupelandt\Desktop\ ##############
gamma 2.4460739712731736
a 1.2298126690193514
b 0.02993465761377105
k 6.788897330864543

Now my next question is, what do I have to do next?
Asign this to a specific monitor? And if so, how?
Or enter this value in the table available in the monitor center? :slight_smile:
Does the gamma correction apply systematically once I select the monitor with the calibration for my experiment? I find it really hard to understand how it works.

Thanks again for your insight!!!

Bill Prinzmetal


I tried this last night and it worked perfectly, so I am more sure I am correct in what follows.
You need to get those 4 numbers for Lum, reg, green and blue (gamma, a, b and k. So you will have to run my .py program 4 times. Then you will have 16 numbers ([gamma, a, b, & k] x 4 (Lum, red, green and blue) = 16 numbers.

Then open up monitor center. You probably should have 2 settings for each lab monitor something:



Fill in the spatial components for both. I would fill them all in including viewing distance and screen width (cm). Save after each change (Top left).

Then select the what will be the gamma corrected monitor (e.g., LG_Monitor_GammaCorrected). On the right panel, middle, will be a table like:

(Attachment PastedGraphic-1.tiff is missing)

(Attachment PastedGraphic-2.pdf is missing)

(Attachment Semi-AutoStimuli is missing)

You have to run my .py program once separately for Lum, R, G, and B. So you will have 32 numbers (parameters [gamma, a, b, and k] x colors (Lum, red grey blue]). Open monitor center, select the monitor you want to use, and enter in the table on the middle right. Have the min value = 0 and the max value = 255. Save the changes to the monitor you have corrected.

I have two monitor setting for each monitor, corrected and uncorrected (e.g., LG_Monitor, LG_Monitor_GammaCorrected). The uncorrected monitor setting will have gamma=1 and the other values (a, b, k)=nan. Here is what my corrected version looks like:

The reason I have corrected and uncorrected values is that if you use real photographs as stimuli they may look better uncorrected. But with uncorrected sine waves and gabor patches will not be truly from sine waves if uncorrected. That is why I have 2 monitor settings for each monitor.

Thank you very much. This explanation is very clear (despite the missing attachments). I will try this tomorrow for sure :slight_smile:
I am a bit surprised though by the fact that you enter 0 and 255 as the min and max values since I thought that these values had to relate to the luminance values in cd/m² corresponding to the 0 and 255 rgb values.

If I understand you correctly, once I enter all the values in the monitor center and select this monitor for my experiment, the correction is then automatically applied? I don’t have to refer to a specific monitor in the code? I guess I can do the test by running the experiment with and without the calibrated monitor. Visually, can you generally observe the differences on simple stimuli such as gratings (when the gamma is around 2.5, like yours)?

By the way, do you usually use the easy or full gamma correction? I suppose we can use the second one since we have the values for the “b”. I don’t really get the difference.

Thanks again for your responsiveness!

To your second question, how do you associate an experiment with a monitor setting. (A single monitor can have several setting, eg, gamma corrected or not.) If you use Builder, you set the monitor setting by copying the monitor setting name, and pasting (or typing) it into Experimental Settings Icon which is in the menu bar. It’s under Screen. If you use coder, the name of the monitor setting is in the window declaration.

The first question, min-max 0 to 255 or 0 to 1? I wasn’t sure. But I made a presentation program like the semi-auto stimulus program with Builder (not as good of course). But I could set it with different monitor settings. When I set it with an uncorrected monitor setting, I got a vaguely logarithmic relation between setting (rgb255 value) and luminance (cd/m**2). After I created a Gamma corrected profile, I took I the measurements again. In this I set the min=0, max=255. I got almost perfect linear functions (for lum, red, green, and blue). So what ever I did was OK. It helps to let your monitor warm up for 10-20 min first. I put my photometer on a tripod.