Return to Report
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Matlab Code for CRT Calibration
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  PR650 Set-up
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Must clear the serial port for PR650 to properly interact with Matlab
ieClearSerialPorts;
% Must set the serial port to the port the PR650 is connected to
SerialPort = 4;
meter = cmeter( SerialPort );

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Color maps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create color maps for each phosphor
% Columns are RGB values, row indicies correspond to digital value
length = 256;
for i = 1:length
    redmap( i,: ) =    [ ( i-1 )/( length-1 )   0                            0  ];
    greenmap( i,: ) = [ 0                           ( i-1 )/( length-1 )    0  ];
    bluemap( i,: ) =   [ 0                           0                            ( i-1 )/( length-1 )];
end
clear i

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  PSD measurements
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Step through the digital values and measure the PSD of each color
for DV = 1:1:length             % for i = start:increment:finish
     % Display a square
     figure( 1 )
     image( DV )
     title( DV )

     % Color it red
     colormap( redmap )
     % Take measurement
     [DataRed(:,DV),wavelength(:,DV)]=getdata(meter);

     % Color it green
     colormap( greenmap )
     % Take measurement
     [DataGreen(:,DV),wavelength(:,DV)]=getdata(meter);

     % Color it blue
     colormap( bluemap )
     % Take measurement
     [DataBlue(:,DV),wavelength(:,DV)]=getdata(meter);
end
clear DV

% Save variables beginning with 'Data' to GammaData.mat
save GammaData Data*

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Phosphor PSDs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create the montior phosphor matrix (i.e. R, G, B PSDs at max)
Monitor = [ DataRed( :,length ) DataGreen( :,length ) DataBlue( :,length )];

figure( 2 )
plot(   wavelength(:,256), Monitor(:,1), '-r', ...
        wavelength(:,256), Monitor(:,2), '-g', ...
        wavelength(:,256), Monitor(:,3), '-b' )
title( 'Monitor Phosphor PSDs' )
xlabel( 'Wavelength [ nm ]' ), ylabel( 'Radiance [ W / m^2 / sr / nm ]' )

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Gamma
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% To create gamma function, sum the PSDs across wavelength and scale by the maximum value of the PSD
GammaTemp = [  sum( DataRed, 1 )
                            sum( DataGreen, 1 )
                            sum( DataBlue, 1 )  ];
ScaledGamma = [ GammaTemp( 1,: )/GammaTemp( 1,length )
                GammaTemp( 2,: )/GammaTemp( 2,length )
                GammaTemp( 3,: )/GammaTemp( 3,length ) ]';

% Plot the measured gamma functions
DV = [ 1:256 ];
figure( 3 )
plot( DV, ScaledGamma( :,1 ), '-r', ...
      DV, ScaledGamma( :,2 ), '-g', ...
      DV, ScaledGamma( :,3 ), '-b' )

% Estimate the gamma with zero intercept
error = [ 100 100 100 ];       % [ rederror greenerror blueerror ]
Gamma = [ 2 2 2 ];             % [ redgamma greengamma bluegamma ]
for g = 2:0.01:3.0
    e = [ 0 0 0 ];                   % running sum of errors
    for DV = 1:length
        Est = ( DV/length )^g;
        e( 1 ) = e( 1 ) + abs( Est - ScaledGamma( DV,1 ));
        e( 2 ) = e( 2 ) + abs( Est - ScaledGamma( DV,2 ));
        e( 3 ) = e( 3 ) + abs( Est - ScaledGamma( DV,3 ));
    end
    for i = 1:3
        if( e( i ) < error( i ))
            error( i ) = e( i );        % new minimum error
            Gamma( i ) = g;         % and the gamma that achieved that
        end
    end
    clear i
end
clear g, clear DV

% Create the estimated gamma functions
DV = [ 1:256 ];
GammaFctRed = (DV./length).^Gamma(1);
GammaFctGreen = (DV./length).^Gamma(2);
GammaFctBlue = (DV./length).^Gamma(3);

% plot the estimated gamma functions
figure( 4 )
hold on
plot( DV, GammaFctRed , '-r' , DV, GammaFctGreen, '-g', DV, GammaFctBlue, '-b' )
plot( DV, ScaledGamma( :,1 ), '.r', DV, ScaledGamma( :,2 ), '-g', DV, ScaledGamma( :,3 ), '-b' )
hold off
title( 'Estimated Gamma Functions' )
xlabel( 'Digital Value' ); ylabel( 'Intensity' )
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Inverse Gamma
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I = [ 0:1/(length-1):1 ];
GammaInvRed = I.^(1/Gamma(1));
GammaInvGreen = I.^(1/Gamma(2));
GammaInvBlue = I.^(1/Gamma(3));

% plot the inverse gamma functions
figure( 5 )
plot( DV, GammaInvRed , '-r*', DV, GammaInvGreen, '-gx', DV, GammaInvBlue, '-b' )
title( 'Inverse Gamma Functions' )
xlabel( 'Intensity' ); ylabel( 'Digital Value' )

% Save Gamma data
save GammaPlots Gamma*
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Gamma Verification
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% To verify the calculated gamma values, convert desired intensities to digital values using the inverse gamma
% function and measure the output intensity.
InvGammaRedMap = [];
InvGammaGreenMap = [];
InvGammaBlueMap = [];

% Convert intensities to digital values
for i = 0:0.1:1.0
    InvGammaRedMap = [  InvGammaRedMap
                                          i^(1/Gamma(1)) 0 0    ];
    InvGammaGreenMap = [   InvGammaGreenMap
                                             0 i^(1/Gamma(2)) 0  ];
    InvGammaBlueMap = [   InvGammaBlueMap
                                           0 0 i^(1/Gamma(3))  ];
end

for i = 1:size( InvGammaRedMap, 1 )
    % Display a square
    figure( 1 )
    image( i )
    Intensity( i )^(1/Gamma(1))
    title( Intensity( i ))
    % Color it red
    colormap( InvGammaRedMap )
    % Take measurement
    [DataRedGamma(:,i),wavelength(:,i)]=getdata(meter);

    figure( 1 )
    image( i )
    title( Intensity( i ))
    % Color it green
    colormap( InvGammaGreenMap )
    % Take measurement
    [DataGreenGamma(:,i),wavelength(:,i)]=getdata(meter);

    figure( 1 )
    image( i )
    title( Intensity( i ))
    % Color it blue
    colormap( InvGammaBlueMap )
    % Take measurement
    [DataBlueGamma(:,i),wavelength(:,i)]=getdata(meter);
end
clear i

MeasuredIntensity = [ sum( DataRedGamma, 1 )
                                  sum( DataGreenGamma, 1 )
                                  sum( DataBlueGamma, 1 )   ];

IntensityOut = [ MeasuredIntensity( 1,: )/MeasuredIntensity( 1,11 )
                         MeasuredIntensity( 2,: )/MeasuredIntensity( 2,11 )
                         MeasuredIntensity( 3,: )/MeasuredIntensity( 3,11 )  ];

% Plot the desired intensity versuses the measured intensity
IntensityIn = [ 0:0.1:1.0 ]
figure( 6 )
plot( IntensityIn, IntensityOut' )
title( 'Gamma Verification' )
xlabel( 'Intensity In' ), ylabel( 'Intensity Out' )
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Phosphor Independence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a color map that contains every combination of RGB values corresponding to intensities 0.2, 0.6, and 1.0
DVMap = [];
IntensityMap = [];
% i, j, k represent the Intensity we'd like to see at the output
for i = 0.2:0.4:1.0
    for j = 0.2:0.4:1.0
        for k = 0.2:0.4:1.0
            % must convert to digital value so correct intensity is displayed on screen
            DVMap = [     DVMap
                                   (i^(1/Gamma(1))) (j^(1/Gamma(2))) (k^(1/Gamma(3))) ];
           % will use the non-scaled intensity values to calculate the ideal thingies.
          IntensityMap = [   IntensityMap
                                        i j k ];
        end
    end
end
clear i, clear j, clear k

% Measure PSD of multi-phosphor colors
for i = 1:27
    % Display a square
    figure( 1 )
    image( i )

    % Color it
    colormap( DVMap )
    % Take measurement
    [DataIndep(:,i),wavelength(:,i)]=getdata(meter);
end
clear i

% figure( 7 )
% plot( DataIndep )

% Ideal = Monitor * IntensityMap';
% figure( 8 )
% plot( Ideal )

% Check for full rank so we can use least-squares approximation
rank( Monitor ) % Rank = 3...good!
for i = 1:27
    rgb(i,:) = Monitor\DataIndep(:,i);
end
clear i

% Calculate Relative Error
IndepError = (rgb - IntensityMap)/IntensityMap;
Error = sort(IndepError, 1 );
Index = [1:27];
figure( 9 )
plot( Index, Error( :,1 ), '-r', Index, Error( :,2 ), '-g', Index, Error( :,3 ), '-b' )
title( 'Relative Error of Phosphor Independence Tests' )

% Plot relative error in RGB values versus intended intensity
figure( 10 )
hold on
plot (IntensityMap(:,1), IndepError(:,1),'r*')
plot (IntensityMap(:,2), IndepError(:,2),'g*')
plot (IntensityMap(:,3), IndepError(:,3),'b*')
title( 'Relative Error of Phosphor Independence Tests' )
xlabel( 'Input Intensity' ), ylabel( 'Percent Error' )
hold off
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Phosphor Independence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a 3x3 matrix that converts monitor RGB values to fly cone sensitivities
load FlyData     % a fat matrix containing the spectral sensitivies of each of the relevant Drosophila cones in the rows
CalibrationMatrix = FlyCones * Monitor;
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Delete the meter - it gets angry if you don't and you'll have to shut Matlab down and restart it
%  before you can use the meter again
delete(meter);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 

% Save all data collected and calculated values
% save Everything
 

Return to Report