Moncalib is the program in MGL that we use to calibrate monitors. It is used to measure with a photometer (PhotoResearch, Minolta or Topcon) the monitor luminance values and then store them in a table that can be used by the initScreen function to make sure you always use a calibrated output. Moncalib talks through a serial interface to these photometers so that you don't have to sit and take each measurement. Depending on settings (how many repeats of each measurement and how finely you sample the output) it can take several hours to run. We typically recommend running the calibration every few months as the output of displays can change over time (very important for projectors with light bulbs that can get darker over time).
Why do we need to calibrate a monitor? There are many reasons. For example, we may want to be able to specify actually units for the luminance that we present in a stimulus (the brightest white on different monitors can have vastly different physical luminance values). We may want to know the spectrum produced by each color channel of a monitor. We may have specific needs for testing color vision. But, here we will concentrate on the issue of linearizing the monitor's gamma.
What is gamma? Well, when you set the color of your output display you typically set values that are between 0 and 255 (sometimes normalized to 0 and 1 - like for OpenGL and MGL functions). Changing the level from 0 to 255 does not linearly increase the intensity of light coming from the monitor. The relationship is typically a non-linear relationship that is approximated as a exponential function like in the graph here:
Why do monitors do this? Well it used to be because of the physical properties of CRT displays, but now monitors are actually built to display in this fashion because they make the display look better (possibly a weber's law kind of thing). In fact, PC makers and Apple typically set their monitors to have gammas and these are different! PC is typically set to 2.2 and Mac to 1.8.
So how do we undo the gamma? Well, when we calibrate the monitor we are trying to make it so that there is a linear relationship between the value we put in our computer programs and what the luminance of the display is. So, we measure the input-output relationship (like the one above) and then invert it so that we can be sure that incrementing values will linearly increment the monitor output. How does that work? Well, you need to know about the gamma table. In your computer display card there is a table that maps each value from 0 to 255 to a finer resolution value (typically in today's computers this is a 10 bit value - though we are hoping that will change to have finer resolution and all the software and hardware will support that). So, when you tell the monitor to go to say 54, then the value is looked up in the table and would come out as some number, 643 for an arbitrary example. Then the display card uses that value to set the luminance of the monitor to a value between 0 and 1024 (assuming a 10 bit table). What we can now do is manipulate that gamma table so that you can insure that the input values from 0 to 255 will range from 0 to 1024 in such a way as to make sure that the output of the monitor is linear with respect to the input values.
Why is this important? If you care about contrast, for one, it is really important. If the monitor is not linearlized and you display a gray value of say 128 and you want to have equal increments of white and decrements of black to make a grating, you might set your values to sinusoidally change from, say 64 - 128 - 192. But, this would not result in equally bright whites as blacks are dark because of the gamma relationship between these input values and output luminance. You would have an overall change in the luminance of the patch as you change contrast. This would not be good. So, we calibrate monitors.
First you need to have a photometer. Moncalib works with three different brands of photometers.
Photometer name | Image | Manual | Comments |
---|---|---|---|
Photo Research SpectraScan 650 | Can make a full set of measurements (including full spectrum measurements) and is considered the gold standard. Our software may work with other models from PhotoResearch, but this is the one we have typically used | ||
Topcon SR-3A-L1 Spectroradiomter | English manual | Similar to the PR650 in capabilities | |
Minolta LS100 | Measures only luminance. Need to also buy LSA-15 Cable which adapts the output to serial. | ||
Minolta CS100a | Instruction manual Communication manual | Measures luminance and chrominance. Need to also buy LSA-15 Cable which adapts the output to serial. |
Our code may work with different models, but we have only tested the above listed models. If you want to use another photometer you can input the readings manually or consider writing a few lines of code in moncalib to support your photometer type.
Note that there are some commercially available devices to calibrate monitor screens which create color profiling information. We have tested one of these called Spyder2Pro which allows you to linearize the monitor output but found that is not yet suitable for psychophysics purposes. The calibration program crashes when you use the default settings to linearize the monitor (an email to the tech support confirmed this is a bug in their software). Using advanced settings it worked but it could only test luminance at 5 output levels. The linearization that it achieved was not accurate enough when tested with the PR650 (it looked like they are doing some sort of spline fit of the points and the luminance as a function of monitor output level looked like a wavy line around the ideal).
You will also need an adaptor to connect the USB on your computer to the photometer. Make sure you have a good device - cause this is typically the reason why you might have a problem connecting to your photometer. Some work, some don't. Some break when you upgrade your OS. Why? Because they rely on driver software that the developers don't really spend so much time making sure works perfectly. That is, they are buggy. So, if things don't work, it is very likely that you don't have a good USB/Serial device driver. Here is what we know has worked for us and what has not.
USB/Serial device | Image | Driver version | Comments |
---|---|---|---|
Plugable USB to RS-232 DB9 Serial Adapter | Prolific driver 1.5.1 Prolific driver, compatible with Sonoma | Update: works with Minolta CS100a as well, with the right driver. Works with the Topcon | |
Keyspan High-Speed USB to Serial Adapter USA-19HS | Mac OS X 10.9.x to 10.11.x Version 2.6 Try this if that link is broken or look for 'USA-19HS' here | Works with Minolta CS100a. We used to use other versions of this device Keyspan USA-28 which worked with PR650 and a white translucent Keyspan USA-28X B which did not work. The Keyspan USA website does not yet have support for OS Sonoma. |
Typically you can just connect the USB/Serial device to the Serial cable of the photometer, but for the Topcon you will need a nullmodem connector between the two (this swaps the read/write lines for communication). It looks like this (remember this should only be necessary for Topcon).
Most display cards typically have 10 bit gamma tables - we test this by incrementing the output values by 1/1024 and making sure that this increments the luminance and making sure that this increases the luminance (an 8 bit card will show ladder steps because it will only change the luminance as you increase by 1/256). This can be tested using moncalib('bitTest=1');
The NVIDIA GeForce series of video cards have 10 bit gamma tables (these are the only ones we have tested):
ATI 10 bit cards:
It is always the best to use the bit test in moncalib because some drivers do not allow 10-bit control on 10-bit DAC cards. You can also query the display card to see if it says that it supports a 10 bit gamma:
displayInfo = mglDescribeDisplays
Check the field gammaTableWidth to see if it is 10.
First, you will want to test the USB/Serial connection. You can do that with the following steps:
>> moncalib('commTest=1') (moncalib) PhotometerTest using serial port. Make sure your device is connected and ready to go Which photometer are you using? 0=quit 1-Photo Research [PR650] 2-Minolta [LS-100] 3-Minolta [CS-100a] 4-Topcon [SR-3A]) ================== 3
1: cu.Bluetooth-Incoming-Port 2: cu.Bluetooth-Modem 3: cu.KeySerial1 4: cu.USA19H2421P1.1 Choose a serial device (0 to quit)4
Please turn on the LS100 and press the white F key at the same time. The LCD panel on the LS100 should end with a "C" Is there a "C" at the end (y/n)? y
(moncalib:photometerTest) Trying to make a measurement from your photometer. If the code hangs here, there is probably a communication problem. A few things to try: 1) Unplug your serial adaptor from the computer and plug it back in again. 2) Restart Matlab 3) Reboot the computer (sometimes the serial adaptor needs a good kick in the pants) 4) Check to make sure you have the correct cable (For example, the Topcon needs a null-modem cable that crosses read/write lines, while other photometers may need a simple pass through cable). 5) Make sure that your communication mode on the device is setup correctly. Minolta can only use 4800/even/7 bits/2 stop bits. Other photometers have different settings, but should be set to 9600/none/8/1 6) Power cycle your photometer and try again. (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) 0 bytes available (moncalib:readSerialPortUsingComm) Reading 28 bytes (moncalib:readSerialPortUsingComm) Received OK13, 33.40, .3729, .4013 (moncalib:readSerialPortUsingComm) 0 bytes available Luminance=33.400000 cd/m^-2 ============================ Photometer measurement has been made =============================== (moncalib:photometerTest) Measured luminace=33.400000 x=0.372900 y=0.401300 =================================================================================================
Each photometer is a bit different in how you get it setup for serial mode. The section below describes the procedure for each of the photometers we have worked with.
First make sure that the topcon has the correct serial port settings, by pushing the [MODE] key for about 2 seconds to enter the function mode. Then push the [ENTER] key four times to set the RS-232C Parameters. The settings should be Baud rate: 9600, Length=8, parity=NONE, Stop bit=1. Use the [CHANGE],[ROTATION] & [ENTER] keys accordingly.
Then make sure that the data communication method is set to Normal Type. From the function mode (see above) hit [ENTER] five times. It should say:
Hold down F while turning on and make sure that the screen displays a small C.
There are a few points that you should pay special attention to:
PR650 REMOTE MODE (XFER) s/w ver 1.02 CMD 51 NAK
This indicates that you pressed the return while the photometer is waiting for a transfer signal (not sure what it is), and hence entered the XFER mode. If you wait another 2 secs or so it will enter the control mode, now press 'return' you should see this:
PR650 REMOTE MODE (CTRL) s/w ver 1.19 CMD B
Basically there is about 2-3 secs time window you should press 'return' to get to this state.
Over the years, we've run into a few issues calibrating with the PR650. While it's the best photometer we have, it can be quite finicky and frustrating. Here are some things to keep in mind and to try when things go wrong.
moncalib('initWaitTime=60');
(moncalib) Displaying data for calibration file /Users/steeve/proj/mgl/task/displays/0001_sr14-3fa8fef553_141110 (moncalib) Calibration took 00:57:57 (moncalib) Calibration measured on 10-Nov-2014 13:42:13 (moncalib) Measured gamma with stepsize: 0.003906 (1/256), numRepeats: 4 (moncalib) Measured table correction with stepsize: 0.003906 (1/256), numRepeats: 4
There are a number of parameters to set, check help moncalib for a full description, but some things of interest are
Parameter | Default | Comments |
---|---|---|
numRepeats | 4 | How many times to repeat measurements - the more the longer, but more accurate |
stepsize | 1/256 | Steps of values to take in testing. To test all 256 values you would do 1/256 (values in MGL are specified from 0 to 1 and not 0 to 256 |
initWaitTime | 0 | How long to wait before starting, you can set this to something long enough in seconds to let you run out of the room |
spectrum | 0 | Collect a spectrum measurement - works only with Topcon |
bitTest | 0 | Tests the resolution of the gamma table by stepping through and seeing whether you get an increase in luminance - also might want to set bitTestBits, bitEstNumRepeats, bitTestN, bitTestBase - see the help |
tableTest | 1 | After getting calibration, tests that calibration by putting the inverse table into the gamma table and running through values. Should give a nice linear relationship between input and output |
The program moncalib will save a calibration file in the local directory. For you to use this calibration file, you can store it in one of two places. Either in your own program directory under a directory called displays:
./displays
Or you can store it in the general displays directory
mgl/task/displays
InitScreen should automatically find the correct table by checking your computer name and looking for the file in these two places. If you do not use the standard filename, or have multiple calibrations for the same computer (like if you have multiple monitors calibrated), you can use a specific file by setting myscreen.calibFilename
myscreen.calibFilename = 'mycalibrationfile.mat'; myscreen = initScreen(myscreen);
Note that the calibFilename can be a literal filename as in the above, or you can specify a portion of the name that will get matched in a file from the displays directory (e.g. computername_displayname would matcha any file in the displays directory that looks like *computername_displayname*.mat).
The name of the file usually created by moncalib will be:
xxxx_computername_yymmdd.mat
Where xxxx is a sequential number starting at 0001 and yymmdd is the date of the calibration. This stores a variable called calib which contains all the information about the calibration. You can quickly plot the data in calib by doing:
load 0001_stimulus-g5_LCD_061004 moncalib(calib);
The most important field of calib is the table field which holds the inverse lookup table to linearize the monitor.