spitschan / SilentSubstitutionToolbox

Toolbox to simulate colorimetric observers for evaluation of photoreceptor isolation
Other
7 stars 5 forks source link

SSTReceptor based demo for ReceptorIsolate #29

Closed JorisVincent closed 6 years ago

JorisVincent commented 6 years ago

Since the SST has moved to using SSTReceptor class and its derivatives, I rewrote the basic parts of the ReceptorIsolateDemo to demonstrate this.

In the process, I ended up making some changes to plotSpectralSensitivities. I also created a function to generate the B_primary for an N-LED device.

A few things to note/discuss:

  1. This new demo lives side by side with the old one (ReceptorIsolateDemo.m), rather than replacing it. I figured it's not my place to replace it.
  2. Under /SST/ReceptorIsolate/dev, there was already a stub of a SSTReceptorIsolateDemo.m. I have not removed this, since I'm not sure whether my demo fulfills all the requirements of this new demo too.
  3. My demo makes use of the original ReceptorIsolate.m, NOT the new ReceptorIsolateOptimBackgroundMulti.m.
  4. Related to (2), under /SST/ReceptorIsolate/dev, there is also a ReceptorIsolateOptim.m, that is close, but not identical to ReceptorIsolateOptimBackgroundMulti.m.
  5. My demo uses T_energyNormalized, just like the old ReceptorIsolateDemo.m. The other /dev/SSTReceptorIsolateDemo.m seems to use T_energy, with ReceptorIsolateOptim. If I use T_energy in my demo, it does not always work. Example: I can create an S-cone isolating direction, but not an L-cone isolating one...
spitschan commented 6 years ago

Thanks!

Re (2) and (4): I've removed the folders and SST/dev ReceptorIsolate/dev since it's random bits of experimental code that shouldn't be in a public repo.

Re (5): I tried running it, see demo below. Could you create a demo code which does not work?

spitschan commented 6 years ago
Available receptor models:
    [1] Human cones, penumbral cones, rods, and melanopsin
Enter model number [1]: 
Observer age (years)? [32]: 
Field size (degrees)? [27.5]: 
Pupil diameter (mm)? [4.7]: 
Include penumbral cones [1 = yes, 0 = no]? [1]: 
* Setting up receptor object with parameters:
  Age [yrs]:            32
  Pupil diameter [mm]:      4.70
  Field size [deg]:     27.50
  Including penumbral cones?:   True

Available devices:
    [1] OneLight: Brainard/Aguirre lab OneLight device, and corresponding calibration data
    [2] Spectral: Hypothetical ideal spectrum producing device (delta function primaries at each wavelength with unit power)
    [3] Monitor: Some typical monitor (supplied by PTB)
    [4] FiveLED: Hypothetical device with five LED primaries
Enter device number [1]: 
Device [1] selected: OneLight (Brainard/Aguirre lab OneLight device, and corresponding calibration data)

Target [1], Silence [2], or Ignore [3] receptor:
    LCone [3]: 1
    MCone [3]: 2
    SCone [3]: 2
    Mel [3]: 2
    Rod [3]: 
    LConePenumbral [3]: 
    MConePenumbral [3]: 
    SConePenumbral [3]: 
Seeking direction that isolates LCones,
while silencing MCones, SCones, Mels,...done.

Nominal contrasts (energy):
    LCone: 26.50% contrast (background = 3.19e+00, direction = 4.03e+00)
    MCone: 0.00% contrast (background = 2.69e+00, direction = 2.69e+00)
    SCone: -0.00% contrast (background = 5.82e-01, direction = 5.82e-01)
    Mel: -0.00% contrast (background = 1.66e+00, direction = 1.66e+00)
    Rod: -10.62% contrast (background = 2.10e+00, direction = 1.88e+00)
    LConePenumbral: 28.47% contrast (background = 3.26e+00, direction = 4.19e+00)
    MConePenumbral: 1.30% contrast (background = 2.79e+00, direction = 2.83e+00)
    SConePenumbral: 12.22% contrast (background = 5.71e-01, direction = 6.41e-01)
spitschan commented 6 years ago

@JorisVincent It looks like the subplot assignment in SSTReceptorIsolateDemo is broken, sometimes assuming 3 columns, sometimes 4. Could you please fix this as intended?

screen shot 2017-11-06 at 20 51 00
JorisVincent commented 6 years ago

The current version of the demo works for all directions. But when I replace T_energyNormalized with T_energy, I get the following (see below). I'm not sure whether I should be using T_energy, or T_energyNormalized, or why it should even make a differene?

Available receptor models:
    [1] Human cones, penumbral cones, rods, and melanopsin
Enter model number [1]: 
Observer age (years)? [32]: 
Field size (degrees)? [27.5]: 
Pupil diameter (mm)? [4.7]: 
Include penumbral cones [1 = yes, 0 = no]? [1]: 
* Setting up receptor object with parameters:
  Age [yrs]:            32
  Pupil diameter [mm]:      4.70
  Field size [deg]:     27.50
  Including penumbral cones?:   True

Available devices:
    [1] OneLight: Brainard/Aguirre lab OneLight device, and corresponding calibration data
    [2] Spectral: Hypothetical ideal spectrum producing device (delta function primaries at each wavelength with unit power)
    [3] Monitor: Some typical monitor (supplied by PTB)
    [4] FiveLED: Hypothetical device with five LED primaries
Enter device number [1]: 
Device [1] selected: OneLight (Brainard/Aguirre lab OneLight device, and corresponding calibration data)

Target [1], Silence [2], or Ignore [3] receptor:
    LCone [3]: 1
    MCone [3]: 2
    SCone [3]: 2
    Mel [3]: 
    Rod [3]: 
    LConePenumbral [3]: 
    MConePenumbral [3]: 
    SConePenumbral [3]: 
Seeking direction that isolates LCones,
while silencing MCones, SCones,...done.

Nominal contrasts (energy):
    LCone: 0.00% contrast (background = 2.99e+18, direction = 2.99e+18)
    MCone: 0.00% contrast (background = 2.25e+18, direction = 2.25e+18)
    SCone: 0.00% contrast (background = 1.85e+17, direction = 1.85e+17)
    Mel: 0.00% contrast (background = 6.26e+16, direction = 6.26e+16)
    Rod: 0.00% contrast (background = 1.33e+18, direction = 1.33e+18)
    LConePenumbral: 0.00% contrast (background = 2.76e+18, direction = 2.76e+18)
    MConePenumbral: 0.00% contrast (background = 2.05e+18, direction = 2.05e+18)
    SConePenumbral: 0.00% contrast (background = 1.50e+17, direction = 1.50e+17)Available receptor models:
    [1] Human cones, penumbral cones, rods, and melanopsin
Enter model number [1]: 
Observer age (years)? [32]: 
Field size (degrees)? [27.5]: 
Pupil diameter (mm)? [4.7]: 
Include penumbral cones [1 = yes, 0 = no]? [1]: 
* Setting up receptor object with parameters:
  Age [yrs]:            32
  Pupil diameter [mm]:      4.70
  Field size [deg]:     27.50
  Including penumbral cones?:   True

Available devices:
    [1] OneLight: Brainard/Aguirre lab OneLight device, and corresponding calibration data
    [2] Spectral: Hypothetical ideal spectrum producing device (delta function primaries at each wavelength with unit power)
    [3] Monitor: Some typical monitor (supplied by PTB)
    [4] FiveLED: Hypothetical device with five LED primaries
Enter device number [1]: 
Device [1] selected: OneLight (Brainard/Aguirre lab OneLight device, and corresponding calibration data)

Target [1], Silence [2], or Ignore [3] receptor:
    LCone [3]: 1
    MCone [3]: 2
    SCone [3]: 2
    Mel [3]: 
    Rod [3]: 
    LConePenumbral [3]: 
    MConePenumbral [3]: 
    SConePenumbral [3]: 
Seeking direction that isolates LCones,
while silencing MCones, SCones,...done.

Nominal contrasts (energy):
    LCone: 0.00% contrast (background = 2.99e+18, direction = 2.99e+18)
    MCone: 0.00% contrast (background = 2.25e+18, direction = 2.25e+18)
    SCone: 0.00% contrast (background = 1.85e+17, direction = 1.85e+17)
    Mel: 0.00% contrast (background = 6.26e+16, direction = 6.26e+16)
    Rod: 0.00% contrast (background = 1.33e+18, direction = 1.33e+18)
    LConePenumbral: 0.00% contrast (background = 2.76e+18, direction = 2.76e+18)
    MConePenumbral: 0.00% contrast (background = 2.05e+18, direction = 2.05e+18)
    SConePenumbral: 0.00% contrast (background = 1.50e+17, direction = 1.50e+17)
spitschan commented 6 years ago

The normalized energy fundamentals and the unnormalized energy fundamentals differ just by a scalar, which is different for each receptor.

I.e.,

k = 1 ./ max(T_energy)
T_energyNormalized = k .* T_energy;

So when you calculate contrast, you would calculate it as:

[T_energyNormalized*(modSpd-bgSpd)] ./ [T_energyNormalized*(bgSpd)]

If you plug in k .* T_energy into T_energyNormalized, you'll see that the k just cancels out.

So, doesn't make a different.

I suspect the reason why you don't get the desired result is that there is a weird mathematical quirk in MATLAB. Take a note of the scale of T_energy. It's at 10^17 or 10^18 and the optimization might not work on these quantities.

Why these numbers are so high, I'm not sure. Tagging @DavidBrainard here to see if that's expected.