This page introduces how to calculate the relative stimulation of ipRGCs with blue and red stimuli.
Prof. Tsujimura defines ipRGC stimulation using a unit of luminance. One ipRGC stimulation was defined as the level of ipRGC stimulation produced by an equal energy spectrum of luminance 1 cd/ m2. The ipRGC stimulation is the sum of the converted spectral values of the sensitivity curves with adjusted luminance.
And Luminance is defined as a sum of L and M cone stimulations from the sensitivity curves for cones defined by CIE(http://www.cvrl.org).
The procedures are as the followings:
# settings
setwd("~/R/stimulation") # switch directory to the file directory
library(xlsx)
data <- read.xlsx(file = "ReceptorStimulationsSpectrumData_YehLab.xlsx", sheetIndex = 1, header = FALSE)
# get data of spectral sensitivity function & the luminance data of blue and red light.s
raw_data <- data[4:101,1:10]
names(raw_data) <- c("lambda", "L", "M", "S", "ipRGC", "L*0.69284", "M*0.349","lambda", "blue-average", "red-average" )
rownames(raw_data) <- NULL
indx <- sapply(raw_data, is.factor)
raw_data[indx] <- lapply(raw_data[indx], function(x) as.numeric(as.character(x)))
raw_data <- raw_data[, -6:-8]
head(raw_data) # check data
## lambda L M S ipRGC blue-average
## 1 392 0.000604713 0.00053623 0.00901661 0.001732121 6.461e-27
## 2 396 0.001283400 0.00116572 0.01923470 0.003639591 5.256e-27
## 3 400 0.002540730 0.00237208 0.03963080 0.007538417 4.645e-27
## 4 404 0.004623700 0.00443021 0.07693230 0.015167795 4.176e-27
## 5 408 0.007896340 0.00775260 0.13804400 0.028698221 4.110e-06
## 6 412 0.012260700 0.01259490 0.22509100 0.050063873 2.907e-05
## red-average
## 1 2.271e-07
## 2 3.178e-07
## 3 5.283e-07
## 4 5.097e-07
## 5 3.475e-07
## 6 9.981e-08
# data frame used to calculate stimulation of blue and red light
sensitivity_data <- matrix(0, 98, 8)
sensitivity_data <- as.data.frame(sensitivity_data)
colnames(sensitivity_data) <- c("BLUE-L", "BLUE-M", "BLUE-S", "BLUE-ipRGC", "RED-L", "RED-M", "RED-S", "RED-ipRGC")
rownames(sensitivity_data) <- NULL
lamba –> wave length L, M, S –> spectral values of L, M, S-cones on the standard sensitivity curves (from CIE 2006) ipRGC –>spectral values of ipRGC on Prof Tsujimura’s ipRGC sensitivity curves blue-averaged –> spectral values of the blue light stimuli red-averaged –> spectral values of the red light stimuli
Take a glance at what the sensitivity curves look like.
matplot(raw_data[,"lambda"], cbind(raw_data[,"L"], raw_data[,"M"], raw_data[,"S"], raw_data[,"ipRGC"]), xlab = "wave length(nm)", ylab = " ", type = "l", col = cbind("red","green", "black", "blue"), lty = 1)
legend("topright", legend=c("L-cone", "M-cone", "S-cone", "ipRGC"), pch=1, col=c("red","green","black","blue"), horiz=FALSE)
Plot of the spectral values of blue and red light presented in experiments.
matplot(raw_data[,"lambda"], cbind(raw_data[,"blue-average"], raw_data[,"red-average"]), xlab = "wave length(nm)", ylab = "cd/m2", type = "l", col = cbind("blue","red"), lty = 1)
legend("topright", legend=c("blue average", "red average"), pch=1, col=c("blue","red"), horiz=FALSE)
Then start coverting spectral values of blue and red light to ipRGC stimulation.
Also calculate luminance of the blue and red stimuli for adjusting the luminance. Luminance is defined as a sum of L and M cone stimulations.To calculate luminance, time the coefficient weights of L and M (0.69 & 0.34) cones to the to the values of L and M cones of the spectral sensitiivity functions.
lcone_lum <- raw_data["L"]*0.69284
mcone_lum <- raw_data["M"]*0.34967
To calculate stimulation of the actural stimuli, spectral values of blue and red light are mutipled by the spectral value of ipRGC sensitivity curves. Similiarly, the spectral values of blue and red light are mutipled by the spectral values of L and M-cones of sensitivity curves to evaluate the luminance.
sensitivity_data["BLUE-L"] <- lcone_lum * raw_data["blue-average"]
sensitivity_data["BLUE-M"] <- mcone_lum * raw_data["blue-average"]
sensitivity_data["BLUE-S"] <- raw_data["S"] * raw_data["blue-average"]
sensitivity_data["BLUE-ipRGC"] <- raw_data["ipRGC"] * raw_data["blue-average"]
sensitivity_data["RED-L"] <- lcone_lum * raw_data["red-average"]
sensitivity_data["RED-M"] <- mcone_lum * raw_data["red-average"]
sensitivity_data["RED-S"] <- raw_data["S"] * raw_data["red-average"]
sensitivity_data["RED-ipRGC"] <- raw_data["ipRGC"] * raw_data["red-average"]
sensitivity_data[is.na(sensitivity_data)] <- 0 # convert NA to 0
head(sensitivity_data) # quick check of the sensitivity data
## BLUE-L BLUE-M BLUE-S BLUE-ipRGC RED-L
## 1 2.706961e-30 1.211460e-30 5.825632e-29 1.119124e-29 9.514794e-11
## 2 4.673587e-30 2.142437e-30 1.010976e-28 1.912969e-29 2.825849e-10
## 3 8.176683e-30 3.852773e-30 1.840851e-28 3.501595e-29 9.299767e-10
## 4 1.337775e-29 6.469090e-30 3.212693e-28 6.334071e-29 1.632816e-09
## 5 2.248540e-08 1.114160e-08 5.673608e-07 1.179497e-07 1.901138e-09
## 6 2.469410e-07 1.280260e-07 6.543395e-06 1.455357e-06 8.478563e-10
## RED-M RED-S RED-ipRGC
## 1 4.258205e-11 2.047672e-09 3.933648e-10
## 2 1.295408e-10 6.112788e-09 1.156662e-09
## 3 4.381959e-10 2.093695e-08 3.982546e-09
## 4 7.895821e-10 3.921239e-08 7.731025e-09
## 5 9.420209e-10 4.797029e-08 9.972632e-09
## 6 4.395691e-10 2.246633e-08 4.996875e-09
matplot(raw_data[,"lambda"], cbind(sensitivity_data[,"BLUE-ipRGC"], sensitivity_data[,"RED-ipRGC"]), xlab = "wave length(nm)", ylab ="cd/m2", type = "l", col = cbind("blue","red"), lty = 1)
legend("topright", legend=c("blue ipRGC", "red ipRGC"), pch=1, col=c("blue","red"), horiz=FALSE)
Obviously stimulation with blue light stimuli is larger than red stimuli.
senFunSums <- colSums(sensitivity_data)
stimulations <- matrix(0, 2, 5)
rownames(stimulations) <- c("BLUE", "RED")
colnames(stimulations) <- c("L", "M", "S", "ipRGCs", "Luminance")
# creating a table of pre-adjusted stimulations
for (i in 1 : length(senFunSums)) {
# assign row index
if (i <= length(senFunSums)/2) {
rowIndex <- 1
} else rowIndex <- 2
# assign col index
if (i %% 4 !=0) {
colIndex <- i %% 4
} else colIndex <- 4
# calculating pre-adjusted stimulations
# and fill adjusted data into the new data frame
if (i%%4 == 1 | i%%4 == 2 ){
stimulations[rowIndex, colIndex] <- senFunSums[i]*683
} else if (i %% 4 == 3) {
stimulations[rowIndex, colIndex] <- senFunSums[i]*1466
} else if (i %% 4 == 0) {
stimulations[rowIndex, colIndex] <- senFunSums[i]*872
#683, 1466, 872 are the constants to calculate the luminance
# from the spectrum and sensitivty curve, so called "Km".
# and its unit is lm/W
}
}
stimulations
## L M S ipRGCs Luminance
## BLUE 2.653317 2.0261725 42.6447173 19.431430 0
## RED 2.671399 0.4579188 0.1529893 0.283531 0
Prof. Tsujimura assumes that neither the S cones nor the ipRGC affect the photopic luminance efficiency function (i.e., luminance), therefore lumiance equals to (L-cone + M-cone) in both blue and right.
stimulations[1, 5] <- stimulations[1,1]+stimulations[1,2]
stimulations[2, 5] <- stimulations[2,1]+stimulations[2,2]
stimulations
## L M S ipRGCs Luminance
## BLUE 2.653317 2.0261725 42.6447173 19.431430 4.679489
## RED 2.671399 0.4579188 0.1529893 0.283531 3.129318
Prof. Tsujimura assumes that that red and blue stimuli were isoluminant, so adjust the stimulation according to the ratio of blue- and red- luminance.
# adjust to same luminance
stimulations[2,] <- stimulations[2,] * (stimulations[1,5]/stimulations[2,5])
stimulations
## L M S ipRGCs Luminance
## BLUE 2.653317 2.0261725 42.6447173 19.4314297 4.679489
## RED 3.994731 0.6847581 0.2287756 0.4239838 4.679489
# calculate the relative stimulations by dividing all values
stimulations[1, ] <- stimulations[1,]/stimulations[2,]
stimulations[2, ] <- stimulations[2,]/stimulations[2,]
# check the relative stimulation
stimulations
## L M S ipRGCs Luminance
## BLUE 0.6642041 2.958961 186.4041 45.8306 1
## RED 1.0000000 1.000000 1.0000 1.0000 1
The stimulation of ipRGC with blue light is about 46 times larger than red light.