|
12 | 12 | case 'tracking' |
13 | 13 | whichCalFile = 'ViewSonicG220fb.mat'; |
14 | 14 | whichCalNumber = 1; |
15 | | - nDeviceBits = 8; |
| 15 | + nDeviceBits = 10; |
16 | 16 | whichCones = 'ss2'; |
17 | 17 | NOAMBIENT = false; |
18 | 18 | case 'detection' |
|
237 | 237 |
|
238 | 238 | % Make a plot of the gamut in the LS contrast plane |
239 | 239 | figure; clf; hold on; |
240 | | -%plot(100*gamutContrast(1,:),100*gamutContrast(3,:),'ko','MarkerSize',8); |
241 | 240 | plot([-100 100],[0 0],'k:','LineWidth',0.5); |
242 | 241 | plot([0 0],[-100 100],'k:','LineWidth',0.5); |
243 | 242 | plot(100*gamutContrast(1,:),100*gamutContrast(3,:),'k','LineWidth',2); |
|
336 | 335 | expContrastLMS = [expContrastLMS ; LMSstimulusContrast('experiment',expNameCell{ii})]; |
337 | 336 | end |
338 | 337 | for ii = 1:size(expContrastLMS,1) |
339 | | - targetAngle(ii) = atand(expContrastLMS(ii,2),expContrastLMS(ii,1)); |
340 | | - targetContrast(ii) = norm([expContrastLMS(ii,1) expContrastLMS(ii,2)]); |
| 338 | + targetAnglesFromFunction(ii) = round(atand(expContrastLMS(ii,3)/expContrastLMS(ii,1)),2); |
| 339 | + targetContrastsFromFunction(ii) = norm([expContrastLMS(ii,1) expContrastLMS(ii,3)]); |
341 | 340 | end |
342 | 341 |
|
343 | | - targetAngleRaw = theSpecificAngles; |
344 | | - targetContrast = specificVectorLengthContrast; |
345 | | - case {'detection', 'detectionRaw'}; |
| 342 | + % Get unique angles, dealing with 180 degree symmetry. |
| 343 | + targetAngleRaw = unique(targetAnglesFromFunction); |
| 344 | + |
| 345 | + for aa = 1:length(targetAngleRaw) |
| 346 | + index = find(targetAnglesFromFunction == targetAngleRaw(aa)); |
| 347 | + targetContrast(:,aa) = targetContrastsFromFunction(index); |
| 348 | + end |
| 349 | + case {'detection', 'detectionRaw'} |
346 | 350 | % Options are 'MAB', 'BMC', 'KAS' |
347 | 351 | contrastLim = 0.3; |
348 | 352 | contrastDevLim = 0.015; |
|
360 | 364 | % Don't care about length here as that is handled by the contrast |
361 | 365 | % maximization code below. |
362 | 366 | targetContrastDir = [cosd(targetAngle(cc,aa)) 0 sind(targetAngle(cc,aa))]'; |
363 | | - targetConeContrast(:,cc,aa) = (targetContrast(cc,aa)*targetContrastDir); |
| 367 | + targetConeContrast(:,cc,aa) = (imageScaleFactor*targetContrast(cc,aa)*targetContrastDir); |
364 | 368 |
|
365 | 369 | % Convert from cone contrast to cone excitation direction. |
366 | 370 | % Don't care about length here as that is handled by the contrast |
|
376 | 380 | % Go back to contrast with both calibrations |
377 | 381 | obtainedCones(:,cc,aa) = SettingsToSensor(calObjCones,theSettings); |
378 | 382 | obtainedCones1(:,cc,aa) = SettingsToSensor(calObjCones1,theSettings); |
379 | | - obtainedConeContrast(:,cc,aa) = ((obtainedCones(:,cc,aa)-bgCones) ./ bgCones); |
380 | | - obtainedConeContrast1(:,cc,aa) = ((obtainedCones1(:,cc,aa)-bgCones1) ./ bgCones1); |
| 383 | + obtainedConeContrast(:,cc,aa) = ((obtainedCones(:,cc,aa)-bgCones) ./ bgCones)/imageScaleFactor; |
| 384 | + obtainedConeContrast1(:,cc,aa) = ((obtainedCones1(:,cc,aa)-bgCones1) ./ bgCones1)/imageScaleFactor; |
381 | 385 |
|
382 | 386 | % Need to deal with angle flipping which can happen for small |
383 | 387 | % contrasts. |
384 | | - obtainedAngle(cc,aa) = atand(obtainedConeContrast(3,cc,aa)/obtainedConeContrast(1,cc,aa)); |
| 388 | + obtainedAngle(cc,aa) = round(atand(obtainedConeContrast(3,cc,aa)/obtainedConeContrast(1,cc,aa)),2); |
385 | 389 | if (targetAngle(cc,aa) > 0 && obtainedAngle(cc,aa) < 0) |
386 | 390 | obtainedAngle(cc,aa) = obtainedAngle(cc,aa) + 180; |
387 | 391 | end |
388 | 392 | if (targetAngle(cc,aa) < 0 && obtainedAngle(cc,aa) > 0) |
389 | 393 | obtainedAngle(cc,aa) = obtainedAngle(cc,aa) - 180; |
390 | 394 | end |
391 | | - obtainedAngle1(cc,aa) = atand(obtainedConeContrast1(3,cc,aa)/obtainedConeContrast1(1,cc,aa)); |
| 395 | + obtainedAngle1(cc,aa) = round(atand(obtainedConeContrast1(3,cc,aa)/obtainedConeContrast1(1,cc,aa)),2); |
392 | 396 | if (targetAngle(cc,aa) > 0 && obtainedAngle1(cc,aa) < 0) |
393 | 397 | obtainedAngle1(cc,aa) = obtainedAngle1(cc,aa) + 180; |
394 | 398 | end |
|
401 | 405 | angleDeviation1(cc,aa) = obtainedAngle1(cc,aa)-targetAngle(cc,aa); |
402 | 406 | contrastDeviation(cc,aa) = obtainedContrast(cc,aa) - targetContrast(cc,aa); |
403 | 407 | contrastDeviation1(cc,aa) = obtainedContrast1(cc,aa) - targetContrast(cc,aa); |
| 408 | + MConeDeviation(cc,aa) = obtainedConeContrast(2,cc,aa); |
| 409 | + MConeDeviation1(cc,aa) = obtainedConeContrast1(2,cc,aa); |
404 | 410 |
|
405 | | - % Figure out the cone excitations for the settings we computed, and |
406 | | - % then convert to contrast as our maximum contrast in this direction. |
407 | | - % |
408 | | - % Dividing by imageScaleFactor handles the sine phase of the Gabor |
| 411 | + % Report out |
409 | 412 | fprintf(' Target contrasts: L cone contrast %7.3f%%, M, %7.3f%%, S %7.3f%%, angle %7.1f, vector length %0.1f%%\n', ... |
410 | 413 | 100*targetConeContrast(1,cc,aa),100*targetConeContrast(2,cc,aa),100*targetConeContrast(3,cc,aa), ... |
411 | 414 | targetAngle(cc,aa),100*targetContrast(cc,aa)); |
|
421 | 424 | % Compute values to use |
422 | 425 | targetAngleToUse = mean(obtainedAngle1,1); |
423 | 426 | targetContrastToUse = obtainedContrast1; |
424 | | -figure; clf; hold on; |
425 | | -subplot(2,2,1); hold on; |
| 427 | + |
| 428 | +% Diagnostic plots |
| 429 | +figure; clf; |
| 430 | +set(gcf,'Position',[10 10 800 1200]); |
| 431 | +subplot(3,2,1); hold on; |
426 | 432 | plot(targetAngleRaw,targetAngleToUse,'ro','MarkerFaceColor','r','MarkerSize',10); |
427 | 433 | plot([-100 100],[-100 100],'k'); |
428 | 434 | xlim([-100 100]); ylim([-100 100]); |
429 | 435 | axis('square'); |
430 | 436 | xlabel('Target Angle (deg)'); ylabel('Obtained Angle (deg)'); |
431 | | -subplot(2,2,2); hold on; |
| 437 | +title([whichExperiment ' ' subjID ' Bits ' num2str(nDeviceBits)]); |
| 438 | +subplot(3,2,2); hold on; |
432 | 439 | plot(100*targetContrast(:),100*targetContrastToUse(:),'ro','MarkerFaceColor','r','MarkerSize',10); |
433 | 440 | plot([0 100*contrastLim],[0 100*contrastLim],'k'); |
434 | 441 | xlim([0 100*contrastLim]); ylim([0 100*contrastLim]); |
435 | 442 | axis('square'); |
436 | 443 | xlabel('Target Contrast (%)'); ylabel('Obtained Contrast (%)'); |
437 | | -subplot(2,2,3); hold on; |
| 444 | +subplot(3,2,3); hold on; |
438 | 445 | plot(targetAngleRaw,targetAngleToUse-targetAngleRaw,'ro','MarkerFaceColor','r','MarkerSize',10); |
439 | 446 | plot([-100 100],[0 0],'k'); |
440 | 447 | xlim([-100 100]); ylim([-angleDevLim angleDevLim]); |
441 | 448 | axis('square'); |
442 | 449 | xlabel('Target Angle (deg)'); ylabel('Obtained Angle Deviation (deg)'); |
443 | | -subplot(2,2,4); hold on; |
| 450 | +subplot(3,2,4); hold on; |
444 | 451 | plot(100*targetContrast(:),100*targetContrastToUse(:)-100*targetContrast(:),'ro','MarkerFaceColor','r','MarkerSize',10); |
445 | 452 | plot([0 100*contrastLim],[0 0],'k'); |
446 | 453 | xlim([0 100*contrastLim]); ylim([100*-contrastDevLim 100*contrastDevLim]); |
447 | 454 | axis('square'); |
448 | 455 | xlabel('Target Contrast (%)'); ylabel('Obtained Contrast Deviation (%)'); |
449 | 456 |
|
| 457 | +subplot(3,2,5); hold on; |
| 458 | +plot(100*targetContrast(:),100*MConeDeviation1(:),'ro','MarkerFaceColor','r','MarkerSize',10); |
| 459 | +plot([0 100*contrastLim],[0 0],'k'); |
| 460 | +xlim([0 100*contrastLim]); ylim([100*-contrastDevLim 100*contrastDevLim]); |
| 461 | +axis('square'); |
| 462 | +xlabel('Target Contrast (%)'); ylabel('M Cone Contrast (%)'); |
| 463 | + |
450 | 464 | % The angular deviations start to lose meaning as the contrast gets very |
451 | 465 | % small |
452 | 466 | fprintf('\n Had ambient/cones used been right: Max abs angle deviation %0.4f, max abs vector length deviation %0.4f\n',max(abs(angleDeviation(:))),max(abs(contrastDeviation(:)))); |
|
0 commit comments