/MatlabCode/branches/Greg's Branch/Analysis/gamutCheck.m

http://horwitzlab.googlecode.com/ · MATLAB · 90 lines · 31 code · 11 blank · 48 comment · 4 complexity · 7ddb376084f62c1df9b208164339b22b MD5 · raw file

  1. function [h,scalar] = gamutCheck(cc, bkgndrgb, M, tail)
  2. % function [h,scalar] = gamutCheck(cc, bkgndrgb, M, tail)
  3. %
  4. % Will determine whether a requested cone contrast is physically obtainable
  5. % on the monitor.
  6. %
  7. % OUTPUT
  8. % h: 1 = in gamut, 0 = not in gamut
  9. % scalar: the largest scalar by which cc can be multiplied by and still
  10. % fit inside the gamut.
  11. %
  12. % INPUT
  13. % bkgndrgb: RGBs of the background in normalized intensity units
  14. % cc: Cone contrast desired (direction and amplitude)
  15. % M: The 'M' matrix obtained by taking the dotproducts of the
  16. % phosphor emission spectra and the cone fundamentals
  17. % tail: 'both' means we're checking for a biphasic stimulus (like a
  18. % grating). 'single' means we're checking for a monophasic stimulus.
  19. if (~strcmp(tail,'both') & ~strcmp(tail,'single'))
  20. error('Third argument must be either ''both'' or ''single''');
  21. end
  22. if (size(bkgndrgb,1) < size(bkgndrgb,2))
  23. bkgndrgb = bkgndrgb'; % forcing a column vector
  24. end
  25. if (size(cc,1) < size(cc,2))
  26. cc = cc'; % forcing a column vector
  27. end
  28. % cc
  29. % bkgndrgb
  30. % M
  31. % tail
  32. bkgndlms = M*bkgndrgb;
  33. rgb = inv(M)*(bkgndlms.*(cc)); % rgb is is delta units from bkgnd
  34. scalefactors = [(1-bkgndrgb(1))/rgb(1);...
  35. (1-bkgndrgb(2))/rgb(2);...
  36. (1-bkgndrgb(3))/rgb(3);...
  37. (-bkgndrgb(1))/rgb(1);...
  38. (-bkgndrgb(2))/rgb(2);...
  39. (-bkgndrgb(3))/rgb(3)];
  40. % No flipping about the origin if we're just considering monopolar stimuli
  41. if (strcmp(tail,'single'))
  42. scalefactors(scalefactors < 0) = [];
  43. end
  44. signs = sign(scalefactors);
  45. scalefactors = abs(scalefactors*(1-2*eps)); % A hack to avoid round off errors
  46. % abs to avoid flipping the polarity
  47. collisionpt = [];
  48. for i = 1:size(scalefactors,1)
  49. collisionpt(i,:) = rgb*signs(i)*scalefactors(i)+bkgndrgb;
  50. end
  51. Limpossible = any(collisionpt<0,2) | any(collisionpt>1,2);
  52. scalar = min(abs(scalefactors(~Limpossible)));
  53. h = scalar > 1;
  54. end
  55. % For testing
  56. % M =[0.0715 0.1314 0.0187;...
  57. % 0.0259 0.1366 0.0275;...
  58. % 0.0022 0.0104 0.1042];
  59. %
  60. % bkgndrgb = [.57 .48 .41]'
  61. % cc = [.25 .25 .25]';
  62. %
  63. % Sanity checks.
  64. % rgb intensity at peak
  65. %inv(M)*(bkgndlms+stimlms)
  66. % rgb intensity at trough
  67. %inv(M)*(bkgndlms-stimlms)
  68. % % Should be out
  69. % inv(M)*(bkgndlms.*(1+stimcc))
  70. % inv(M)*(bkgndlms.*(1-stimcc))
  71. %
  72. %
  73. % stimcc./cc and scalar should be equal
  74. % stimrgb = rgb*scalar;
  75. % stimlms = M*stimrgb;
  76. % stimcc = stimlms./bkgndlms;
  77. % stimcc./cc
  78. %
  79. % scalar