OSCR

Model-based analysis of stop-signal data reveals robust neural and clinical correlates of evidence accumulation but not inhibition.

Code ↔ Paper

3 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 3 matches
  1. [1] § METHODS AND MATERIALS › RDEX-ABCD model ↔ Simulation Studies/dmc/models/WALD-ABCDlg_05/dists.R, lines 595–706 · score 0.71 · trigger failure, go failure, Stop signal, exponential, accuracy, race
  2. [2] § METHODS AND MATERIALS › RDEX-ABCD model ↔ Data Preparation/ABCD_SST_subject_selection.R, lines 1–76 · score 0.66 · choice accuracy, incorrect, omissions, Go trials, stimulus, RTs
  3. [3] § METHODS AND MATERIALS › RDEX-ABCD model evaluation and estimation ↔ Modeling and Recovery/interpretation_plots.R, lines 2–40 · score 0.54 · generalized power, RDEX ABCD model, growth, linear, fit

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

R · 1,183 lines · 43 KB · no license · 1 match

  1. ################ Wald exg stop signal with truncaiton in lower bound of exg
  2. ######################## ExGaussian ----
  3. # DISTRIBTION AND RANDOM FUNCTIONS ----
  4. # Modified from gamlss.dist to make cdf in tau > 0.05 * sigma case robust,
  5. # and robust to -Inf and Inf inputs, returns NA for bad sigma or tau and
  6. # robust against small sigma cases. Also changes nu name to tau
  7. pexGAUS <- function (q, mu = 5, sigma = 1, tau = 1, lower.tail = TRUE, log.p = FALSE)
  8. {
  9. if (sigma <= 0) return(rep(NA,length(q)))
  10. if (tau <= 0) return(rep(NA,length(q)))
  11. if (sigma < 1e-4)
  12. return(pexp(q-mu,1/tau,log=log.p,lower.tail=lower.tail)) # shfited exponential
  13. ly <- length(q)
  14. sigma <- rep(sigma, length = ly)
  15. mu <- rep(mu, length = ly)
  16. tau <- rep(tau, length = ly)
  17. index <- seq(along = q)
  18. z <- q - mu - ((sigma^2)/tau)
  19. cdf <- ifelse(is.finite(q),
  20. ifelse(tau > 0.05 * sigma,
  21. pnorm((q - mu)/sigma) -
  22. exp(log(pnorm(z/sigma)) + ((mu + (sigma^2/tau))^2 - (mu^2) -
  23. 2 * q * ((sigma^2)/tau))/(2 * sigma^2)),
  24. pnorm(q, mean = mu, sd = sigma)),
  25. ifelse(q<0,0,1)
  26. )
  27. if (lower.tail == TRUE)
  28. cdf <- cdf
  29. else cdf <- 1 - cdf
  30. if (log.p == FALSE)
  31. cdf <- cdf
  32. else cdf <- log(cdf)
  33. cdf
  34. }
  35. # gamlss.dist function, but returns NA for bad sigma or tau, and
  36. # robust against small sigma cases and changed parameter name nu to tau.
  37. dexGAUS <- function (x, mu = 5, sigma = 1, tau = 1, log = FALSE)
  38. {
  39. if (sigma <= 0) return(rep(NA,length(x)))
  40. if (tau <= 0) return(rep(NA,length(x)))
  41. if (sigma < 1e-4)
  42. return(dexp(x-mu,1/tau,log=log)) # shfited exponential
  43. ly <- length(x)
  44. sigma <- rep(sigma, length = ly)
  45. mu <- rep(mu, length = ly)
  46. tau <- rep(tau, length = ly)
  47. z <- x - mu - ((sigma^2)/tau)
  48. logfy <- ifelse(tau > 0.05 * sigma, -log(tau) - (z + (sigma^2/(2 *
  49. tau)))/tau + log(pnorm(z/sigma)), dnorm(x, mean = mu, sd = sigma,
  50. log = TRUE))
  51. if (log == FALSE)
  52. fy <- exp(logfy)
  53. else fy <- logfy
  54. fy
  55. }
  56. # TRUNCATED VERSIONS ----
  57. # n=100; mu=0; sigma=.05; tau=.1; a=0; b=Inf
  58. rEXG <- function (n,mu=.5,sigma=.05,tau=.1,a=-Inf,b=Inf,max.try=1000)
  59. {
  60. out <- rnorm(n=n, mean=mu,sd=sigma) + rexp(n=n,rate=1/tau)
  61. ok <- (out > a) & (out < b)
  62. if (any(!ok)) {
  63. nneed <- sum(!ok)
  64. nget <- ceiling(1.1*nneed/max(c(mean(ok),.001)))
  65. rtok <- numeric(nneed)
  66. full <- logical(nneed)
  67. n.try=0
  68. repeat {
  69. tmp <- rnorm(n=nget, mean=mu,sd=sigma) + rexp(n=nget,rate=1/tau)
  70. okrt <- (tmp > a) & (tmp < b)
  71. if ( sum(okrt)>=nneed ) {
  72. rtok[!full] <- tmp[okrt][1:nneed]
  73. break
  74. }
  75. ngot <- sum(okrt)
  76. if (ngot>0) {
  77. rtok[!full][1:ngot] <- tmp[okrt]
  78. full[!full][1:ngot] <- TRUE
  79. }
  80. nneed <- nneed - ngot
  81. if (all(!ok))
  82. nget <- nneed*10 else
  83. nget <- ceiling(nneed*2/max(c(mean(ok),.001)))
  84. n.try <- n.try+1
  85. if (n.try==max.try) break
  86. }
  87. out[!ok] <- rtok
  88. }
  89. out
  90. }
  91. dEXG <- function (x, mu = 5, sigma = 1, tau = 1, a=-Inf, b = Inf, log = FALSE)
  92. {
  93. out <- numeric(length(x))
  94. ok <- (x>a) | (x<b)
  95. if (a == -Inf) Fa <- 0 else Fa <- pexGAUS(a,mu=mu,sigma=sigma,tau=tau)
  96. if (b == Inf) Fb <- 1 else Fb <- pexGAUS(b,mu=mu,sigma=sigma,tau=tau)
  97. out <- dexGAUS(x[ok],mu,sigma,tau,log=FALSE)/(Fb-Fa)
  98. if (log) log(out) else out
  99. }
  100. pEXG <- function (q, mu = 5, sigma = 1, tau = 1, a=-Inf, b = Inf,
  101. lower.tail = TRUE, log.p = FALSE)
  102. {
  103. out <- numeric(length(q))
  104. small <- (q<=a); big <- (q>=b); ok <- !small & !big
  105. out[big] <- 1
  106. if (a == -Inf) Fa <- 0 else Fa <- pexGAUS(a,mu=mu,sigma=sigma,tau=tau)
  107. if (b == Inf) Fb <- 1 else Fb <- pexGAUS(b,mu=mu,sigma=sigma,tau=tau)
  108. out[ok] <- (pexGAUS(q[ok],mu,sigma,tau,log.p=FALSE,lower.tail=lower.tail)-Fa)/(Fb-Fa)
  109. if (log.p) log(out) else out
  110. }
  111. # par(mfrow=c(1,2))
  112. # n=1e5;mu=.3;sigma=.2;tau=.2;a=0;b=Inf
  113. # sim <- rEXG(n=n,mu=mu,sigma=sigma,tau=tau,a=a,b=b)
  114. # if (!is.finite(b)) hi <- max(sim) else hi <- b
  115. # tmp=hist(sim,breaks=seq(a,hi,length.out=100),freq=FALSE)
  116. # x=tmp$mids; points(x,dEXG(x,mu=mu,sigma=sigma,tau=tau,a=a,b=b),pch=16,cex=.5)
  117. # plot(x,cumsum(tmp$density)/sum(tmp$density),type="l",ylab="cdf")
  118. # points(x,pEXG(x,mu=mu,sigma=sigma,tau=tau,a=a,b=b),pch=16,cex=.5)
  119. ######################## Wald ----
  120. # n-choice uniformly varying start point (0-A) Wald
  121. # race, with t0, v, A, b (boundary) parameterixaiton
  122. ### Single accumulator model ----
  123. # pigt, digt, rwaldt Copyright (C) 2013 Trisha Van Zandt distributed with:
  124. # Logan, Van Zandt, Verbruggen, and Wagenmakers (2014). On the ability to
  125. # inhibit thought and action: General and special theories of an act of control.
  126. # Psychological Review. Comments and changes added by Andrew Heathcote. Trish's
  127. # code is for k = threshold, a = half width of uniform threshold variability,
  128. # l = rate of accumulation. Note that Wald mean = k/l and shape = k^2.
  129. # Following functions use a different parameterization in terms of v=l (rate),
  130. # uniform start point variability from 0-A (A>=0), threshold b (>0) and hence
  131. # B=b-A (>=0) as a threshold gap. Hence k = b-A/2 = B + A/2 and a=A/2
  132. rWald <- function(n,B,v,A)
  133. # random function for single acumulator
  134. {
  135. rwaldt <- function(n,k,l,tiny=1e-6) {
  136. # random sample of n from a Wald (or Inverse Gaussian)
  137. # k = criterion, l = rate, assumes sigma=1 Browninan motion
  138. # about same speed as statmod rinvgauss
  139. rlevy <- function(n=1, m=0, c=1) {
  140. if (any(c<0)) stop("c must be positive")
  141. c/qnorm(1-runif(n)/2)^2+m
  142. }
  143. flag <- l>tiny
  144. x <- rep(NA,times=n)
  145. x[!flag] <- rlevy(sum(!flag),0,k[!flag]^2)
  146. mu <- k/l
  147. lambda <- k^2
  148. y <- rnorm(sum(flag))^2
  149. mu.0 <- mu[flag]
  150. lambda.0 <- lambda[flag]
  151. x.0 <- mu.0 + mu.0^2*y/(2*lambda.0) -
  152. sqrt(4*mu.0*lambda.0*y + mu.0^2*y^2)*mu.0/(2*lambda.0)
  153. z <- runif(length(x.0))
  154. test <- mu.0/(mu.0+x.0)
  155. x.0[z>test] <- mu.0[z>test]^2/x.0[z>test]
  156. x[flag] <- x.0
  157. x[x<0] <- max(x)
  158. x
  159. }
  160. # Act as if negative v never terminates, cluge to do single accumulator
  161. # case by passing negative v
  162. if (length(v)!=n) v <- rep(v,length.out=n)
  163. if (length(B)!=n) B <- rep(B,length.out=n)
  164. if (length(A)!=n) A <- rep(A,length.out=n)
  165. # Kluge to return -Inf for negative rates, so can implment one accumulator case
  166. out <- numeric(n)
  167. ok <- v>0
  168. nok <- sum(ok)
  169. bs <- B[ok]+runif(nok,0,A[ok])
  170. out[ok] <- rwaldt(nok,k=bs,l=v[ok])
  171. out[!ok] <- Inf
  172. out
  173. }
  174. dWald <- function(t,v,B,A)
  175. # density for single accumulator
  176. {
  177. digt <- function(t,k=1,l=1,a=.1,tiny=1e-10) {
  178. # pdf of inverse gaussian at t with k +/- a/2 uniform variability
  179. # returns digt.0 if a<1e-10
  180. digt.0 <- function(t,k=1,l=1) {
  181. # pdf of inverse gaussian at t with no k variability
  182. # much faster than statmod's dinvgauss funciton
  183. lambda <- k^2
  184. l0 <- l==0
  185. e <- numeric(length(t))
  186. if ( any(!l0) ) {
  187. mu <- k[!l0]/l[!l0]
  188. e[!l0] <- -(lambda[!l0]/(2*t[!l0])) * (t[!l0]^2/mu^2 - 2*t[!l0]/mu + 1)
  189. }
  190. if ( any(l0) ) e[l0] <- -.5*lambda[l0]/t[l0]
  191. x <- exp(e + .5*log(lambda) - .5*log(2*t^3*pi))
  192. x[t<=0] <- 0
  193. x
  194. }
  195. options(warn=-1)
  196. if(length(k)!=length(t)) k <- rep(k,length.out=length(t))
  197. if(length(l)!=length(t)) l <- rep(l,length.out=length(t))
  198. if(length(a)!=length(t)) a <- rep(a,length.out=length(t))
  199. tpos <- t<=0
  200. atiny <- a<=tiny & !tpos
  201. a[atiny] <- 0
  202. ltiny <- (l<=tiny) & !atiny & !tpos
  203. notltiny <- (l>tiny) & !atiny & !tpos
  204. l[l<=tiny] <- 0
  205. x <- numeric(length(t))
  206. # No threshold variability
  207. if ( any(atiny) )
  208. x[atiny] <- digt.0(t=t[atiny],k=k[atiny],l=l[atiny])
  209. # Threshold variability
  210. if ( any(!atiny) ) {
  211. if ( any(notltiny) ) { # rate non-zero
  212. sqr.t <- sqrt(t[notltiny])
  213. term.1a <- -(a[notltiny]-k[notltiny]+t[notltiny]*l[notltiny])^2/(2*t[notltiny])
  214. term.1b <- -(a[notltiny]+k[notltiny]-t[notltiny]*l[notltiny])^2/(2*t[notltiny])
  215. term.1 <- (exp(term.1a) - exp(term.1b))/sqrt(2*pi*t[notltiny])
  216. term.2a <- log(.5)+log(l[notltiny])
  217. term.2b <- 2*pnorm((-k[notltiny]+a[notltiny])/sqr.t+sqr.t*l[notltiny])-1
  218. term.2c <- 2*pnorm((k[notltiny]+a[notltiny])/sqr.t-sqr.t*l[notltiny])-1
  219. term.2d <- term.2b+term.2c
  220. term.2 <- exp(term.2a)*term.2d
  221. term.3 <- term.1+term.2
  222. term.4 <- log(term.3)-log(2)-log(a[notltiny])
  223. x[notltiny] <- exp(term.4)
  224. }
  225. if ( any(ltiny) ) { # rate zero
  226. log.t <- log(t[ltiny])
  227. term.1 <- -.5*(log(2)+log(pi)+log.t)
  228. term.2 <- (k[ltiny]-a[ltiny])^2/(2*t[ltiny])
  229. term.3 <- (k[ltiny]+a[ltiny])^2/(2*t[ltiny])
  230. term.4 <- (exp(-term.2)-exp(-term.3))
  231. term.5 <- term.1+log(term.4) - log(2) - log(a[ltiny])
  232. x[ltiny] <- exp(term.5)
  233. }
  234. }
  235. x[x<0 | is.nan(x) ] <- 0
  236. x
  237. }
  238. out <- numeric(length(t))
  239. ok <- v>0
  240. out[ok] <- digt(t[ok],k=B[ok]+A[ok]/2,l=v[ok],a=A[ok]/2)
  241. out[!ok] <- 0
  242. out
  243. }
  244. pWald <- function(t,v,B,A)
  245. # cumulative density for single accumulator
  246. {
  247. pigt <- function(t,k=1,l=1,a=.1,tiny=1e-10) {
  248. # cdf of inverse gaussian at t with k +/- a/2 uniform variability
  249. # returns pigt.0 if a<=0
  250. pigt.0 <- function(t,k=1,l=1) {
  251. # cdf of inverse gaussian at t with no k variability
  252. # much faster than statmod's pinvgauss funciton
  253. mu <- k/l
  254. lambda <- k^2
  255. e <- exp(log(2*lambda) - log(mu))
  256. add <- sqrt(lambda/t) * (1 + t/mu)
  257. sub <- sqrt(lambda/t) * (1 - t/mu)
  258. p.1 <- 1 - pnorm(add)
  259. p.2 <- 1 - pnorm(sub)
  260. x <- exp(e + log(p.1)) + p.2
  261. x[t<0] <- 0
  262. x
  263. }
  264. options(warn=-1)
  265. if(length(k)!=length(t)) k <- rep(k,length.out=length(t))
  266. if(length(l)!=length(t)) l <- rep(l,length.out=length(t))
  267. if(length(a)!=length(t)) a <- rep(a,length.out=length(t))
  268. tpos <- t<=0
  269. atiny <- a<=tiny & !tpos
  270. a[atiny] <- 0
  271. ltiny <- (l<=tiny) & !atiny & !tpos
  272. notltiny <- (l>tiny) & !atiny & !tpos
  273. l[l<=tiny] <- 0
  274. x <- numeric(length(t))
  275. # No threshold variability
  276. if ( any(atiny) )
  277. x[atiny] <- pigt.0(t[atiny],k[atiny],l[atiny])
  278. # Threshold variability
  279. if ( any(!atiny) ) {
  280. if ( any(notltiny) ) { # rate non-zero
  281. log.t <- log(t[notltiny])
  282. sqr.t <- sqrt(t[notltiny])
  283. term.1a <- .5*log.t-.5*log(2*pi)
  284. term.1b <- exp(-((k[notltiny]-a[notltiny]-t[notltiny]*l[notltiny])^2/t[notltiny])/2)
  285. term.1c <- exp(-((k[notltiny]+a[notltiny]-t[notltiny]*l[notltiny])^2/t[notltiny])/2)
  286. term.1 <- exp(term.1a)*(term.1b-term.1c)
  287. term.2a <- exp(2*l[notltiny]*(k[notltiny]-a[notltiny]) +
  288. log(pnorm(-(k[notltiny]-a[notltiny]+t[notltiny]*l[notltiny])/sqr.t)))
  289. term.2b <- exp(2*l[notltiny]*(k[notltiny]+a[notltiny]) +
  290. log(pnorm(-(k[notltiny]+a[notltiny]+t[notltiny]*l[notltiny])/sqr.t)))
  291. term.2 <- a[notltiny] + (term.2b-term.2a)/(2*l[notltiny])
  292. term.4a <- 2*pnorm((k[notltiny]+a[notltiny])/sqr.t-sqr.t*l[notltiny])-1
  293. term.4b <- 2*pnorm((k[notltiny]-a[notltiny])/sqr.t-sqr.t*l[notltiny])-1
  294. term.4c <- .5*(t[notltiny]*l[notltiny] - a[notltiny] - k[notltiny] + .5/l[notltiny])
  295. term.4d <- .5*(k[notltiny] - a[notltiny] - t[notltiny]*l[notltiny] - .5/l[notltiny])
  296. term.4 <- term.4c*term.4a + term.4d*term.4b
  297. x[notltiny] <- (term.4 + term.2 + term.1)/(2*a[notltiny])
  298. }
  299. if ( any(ltiny) ) { # rate zero
  300. sqr.t <- sqrt(t[ltiny])
  301. log.t <- log(t[ltiny])
  302. term.5a <- 2*pnorm((k[ltiny]+a[ltiny])/sqr.t)-1
  303. term.5b <- 2*pnorm(-(k[ltiny]-a[ltiny])/sqr.t)-1
  304. term.5 <- (-(k[ltiny]+a[ltiny])*term.5a - (k[ltiny]-a[ltiny])*term.5b)/(2*a[ltiny])
  305. term.6a <- -.5*(k[ltiny]+a[ltiny])^2/t[ltiny] - .5*log(2) -.5*log(pi) + .5*log.t - log(a[ltiny])
  306. term.6b <- -.5*(k[ltiny]-a[ltiny])^2/t[ltiny] - .5*log(2) -.5*log(pi) + .5*log.t - log(a[ltiny])
  307. term.6 <- 1 + exp(term.6b) - exp(term.6a)
  308. x[ltiny] <- term.5 + term.6
  309. }
  310. }
  311. x[x<0 | is.nan(x) ] <- 0
  312. x
  313. }
  314. out <- numeric(length(t))
  315. ok <- v>0
  316. out[ok] <- pigt(t[ok],k=B[ok]+A[ok]/2,l=v[ok],a=A[ok]/2)
  317. out[!ok] <- 0
  318. out
  319. }
  320. ######################## Race model ----
  321. rWaldRace <- function(n,v,B,A,t0,return.ttf=FALSE)
  322. # random function for Wald race.
  323. {
  324. B[B<0] <- 0 # Protection for negatives
  325. A[A<0] <- 0
  326. n_v <- ifelse(is.null(dim(v)), length(v), dim(v)[1])
  327. ttf <- matrix(t0 + rWald(n*n_v,B=B,v=v,A=A),nrow=n_v)
  328. if (return.ttf) return(ttf)
  329. resp <- apply(ttf, 2, which.min)
  330. data.frame(RT = ttf[cbind(resp,1:n)], R = apply(ttf, 2, which.min))
  331. }
  332. rWaldexgRace <- function(n,v,B,A,t0,gf=0,a=-Inf,b=Inf,return.ttf=FALSE)
  333. # random function for Wald race.
  334. {
  335. B[B<0] <- 0 # Protection for negatives
  336. A[A<0] <- 0
  337. n_v <- ifelse(is.null(dim(v)), length(v), dim(v)[1])
  338. ttf <- t0 + rbind(rEXG(n,mu=v[1,1],sigma=B[1,1],tau=A[1,1],a=a[1]),
  339. matrix(rWald(n*(n_v-1),B=B[-1,],v=v[-1,],A=A[-1,]),nrow=n_v-1))
  340. if (return.ttf) return(ttf)
  341. resp <- apply(ttf, 2, which.min)
  342. out <- data.frame(RT = ttf[cbind(resp,1:n)], R = apply(ttf, 2, which.min))
  343. if (gf[1] > 0) {
  344. is.gf <- as.logical(rbinom(dim(out)[1],1,gf))
  345. out$RT[is.gf] <- NA
  346. out$R[is.gf] <- 1
  347. }
  348. out
  349. }
  350. n1Wald <- function(dt,v,B,A,t0=0,gf=0)
  351. # Generates defective PDF for responses on node=1, dt (decison time) is a vector of times
  352. {
  353. B[B<0] <- 0 # Protection for negatives
  354. A[A<0] <- 0
  355. n_acc <- ifelse(is.null(dim(v)),length(v),dim(v)[1])
  356. if (is.null(dim(dt))) dt <- matrix(rep(dt,each=n_acc),nrow=n_acc)
  357. # dt <- dt-t0
  358. is.go <- !is.na(dt[1,])
  359. n.go <- sum(is.go)
  360. if (!is.matrix(v)) v <- matrix(rep(v,n.go),nrow=n_acc)
  361. if (!is.matrix(B)) B <- matrix(rep(B,n.go),nrow=n_acc)
  362. if (!is.matrix(A)) A <- matrix(rep(A,n.go),nrow=n_acc)
  363. # Winner
  364. dt[1,is.go] <- (1-gf[1])*dWald(dt[1,is.go],A=A[1,],v=v[1,],B=B[1,])
  365. if (n_acc > 1) for (i in 2:n_acc)
  366. dt[1,is.go] <- dt[1,is.go]*(1-pWald(dt[i,is.go],A=A[i,],v=v[i,],B=B[i,]))
  367. dt[1,!is.go] <- gf[1]
  368. dt[1,]
  369. }
  370. n1Waldexg <- function(dt,v,B,A,Si=1,t0=0,gf=0,minEXG=-Inf)
  371. # Generates defective PDF for responses on node=1, dt (decison time) is a vector of times
  372. {
  373. B[B<0] <- 0 # Protection for negatives
  374. A[A<0] <- 0
  375. n_acc <- ifelse(is.null(dim(v)),length(v),dim(v)[1])
  376. if (is.null(dim(dt))) dt <- matrix(rep(dt,each=n_acc),nrow=n_acc)
  377. # dt[Si,] <- dt[Si,]-t0
  378. # dt <- dt-t0
  379. is.go <- !is.na(dt[1,])
  380. n.go <- sum(is.go)
  381. if (!is.matrix(v)) v <- matrix(rep(v,n.go),nrow=n_acc)
  382. if (!is.matrix(B)) B <- matrix(rep(B,n.go),nrow=n_acc)
  383. if (!is.matrix(A)) A <- matrix(rep(A,n.go),nrow=n_acc)
  384. # Winner
  385. if (Si==1)
  386. dt[1,is.go] <- (1-gf[1])*dEXG(dt[1,is.go],mu = v[1,1],sigma = B[1,1],tau = A[1,1],a=minEXG) else
  387. dt[1,is.go] <- (1-gf[1])*dWald(dt[1,is.go],A=A[1,],v=v[1,],B=B[1,])
  388. if (n_acc > 1) for (i in 2:n_acc)
  389. if (Si==i)
  390. dt[1,is.go] <- dt[1,is.go]*(1-pEXG(q=dt[i,is.go],mu=v[i,1],sigma=B[i,1],tau=A[i,1],a=minEXG)) else
  391. dt[1,is.go] <- dt[1,is.go]*(1-pWald(dt[i,is.go],A=A[i,],v=v[i,],B=B[i,]))
  392. dt[1,!is.go] <- gf[1]
  393. dt[1,]
  394. }
  395. # NB1: no st0
  396. # NB2: TRIALS effect on B (threshold), and values < 0 set to 0
  397. rWaldss <- function (n, v, B, t0, A=0, tf=0, gf=0, ts = 0, minEXG=-Inf,
  398. SSD=Inf, TRIALS = NA, staircase=NA)
  399. # Race among length(v) accumulators (if v a vector),
  400. # or dim(v)[1] (if a matrix), first of which is a stop accumulator.
  401. # Acts the same as rWald except NA returned for RT when winner = 1.
  402. # Optional SSD argument can be used to adjust start time for first
  403. # accumulator. SSD can be a scalar or vector length n; output has an SSD column
  404. # For trials with winning first accumulator RT and R set to NA.
  405. # tf = trigger failure probability, gf = go failure probability
  406. # If any !is.na in staircase runs a staircase
  407. # t0 is a scalar with the standard interpritaiton for GO accumulators.
  408. # minEXG is lower bound on EXG wald
  409. # ts = slope of slowing (speeding if negative) over TRIALS, meanlog - ts*TRIALS
  410. # This has a linear effect on mean and sd
  411. {
  412. if ( length(SSD)==1 ) SSD <- rep(SSD,n)
  413. if ( any(is.na(SSD)) || length(SSD) != n )
  414. stop("SSD cannot have NAs and must be a scalar or same length as n")
  415. n_acc <- ifelse(is.null(dim(v)),length(v),dim(v)[1])
  416. # head start for stop accumulator relative to 0 for go accumulators
  417. t0S <- matrix(rep(c(-t0[1],rep(0,n_acc-1)),length.out=n*n_acc),nrow=n_acc)
  418. if (!is.matrix(v)) v <- matrix(rep(v,n),nrow=n_acc)
  419. if (!is.matrix(B)) B <- matrix(rep(B,n),nrow=n_acc)
  420. if (!is.matrix(A)) A <- matrix(rep(A,n),nrow=n_acc)
  421. if ( !any(is.na(TRIALS)) ) {
  422. if (length(TRIALS)!=n)
  423. stop("TRIALS must have length n")
  424. B[-1,] <- B[-1,] + rep(ts*TRIALS,each=n_acc-1)
  425. }
  426. if ( gf > 0 ) # Setup for GO failure
  427. is.gf <- as.logical(rbinom(length(SSD),1,gf)) else
  428. is.gf <- logical(length(SSD))
  429. if ( all(!is.finite(SSD)) ) { # ALL GO
  430. out <- rWaldRace(n,v=v[-1,,drop=FALSE],B=B[-1,,drop=FALSE],A=A[-1,,drop=FALSE],t0=t0)
  431. out$R <- out$R+1
  432. } else { # SOME STOP
  433. if ( any(is.na(staircase)) ) { # STOP fixed SSD
  434. # add SSD to stop accumulator
  435. t0S[1,] <- t0S[1,] + SSD
  436. out <- rWaldexgRace(n,v=v,B=B,A=A,t0=t0S,a=minEXG)
  437. if ( tf>0 ) {
  438. is.tf <- logical(length(SSD))
  439. is.tf[is.finite(SSD)][as.logical(rbinom(sum(is.finite(SSD)),1,tf))] <- TRUE
  440. if ( any(is.tf) ) {
  441. out[is.tf,] <- rWaldRace(sum(is.tf),v=v[-1,is.tf,drop=FALSE],
  442. B=B[-1,is.tf,drop=FALSE],A=A[-1,is.tf,drop=FALSE],t0=0)
  443. out[is.tf,"R"] <- out[is.tf,"R"]+1
  444. }
  445. }
  446. } else { # STOP, staircase
  447. if ( !is.numeric(staircase) | length(staircase)!=1 )
  448. stop("Staircase must be a numeric vector of length 1 specifying the step.")
  449. SSDi <- SSD[is.finite(SSD)][1] # begining SSD
  450. dt <- rWaldexgRace(n,v=v,B=B,A=A,t0=t0S,return.ttf=TRUE,a=minEXG)
  451. # Setup
  452. winner <- numeric(n)
  453. for ( i in c(1:n) ) {
  454. if ( !is.finite(SSD[i]) ) # not staircase
  455. dt[1,i] <- dt[1,i] + SSD[i] else
  456. dt[1,i] <- dt[1,i] + SSDi # staircase
  457. if ( runif(1)<tf ) # Trigger failure
  458. winner[i] <- which.min(dt[2:n_acc,i])+1 else
  459. winner[i] <- which.min(dt[,i])
  460. if (is.gf[i]) winner[i] <- 1
  461. if ( is.finite(SSD[i]) ) { # update staircase
  462. SSD[i] <- SSDi
  463. if ( winner[i]==1 )
  464. SSDi <- SSDi + staircase else
  465. SSDi <- SSDi - staircase
  466. if (SSDi<1e-10) SSDi <- 0
  467. }
  468. }
  469. out <- data.frame(RT=dt[cbind(winner,1:n)],R=winner)
  470. }
  471. out$RT <- out$RT + t0 # Add t0 for go responses
  472. }
  473. # print(out)
  474. out[out$R==1,"RT"] <- NA
  475. if ( gf > 0 ) {
  476. out$RT[is.gf] <- NA
  477. out$R[is.gf] <- 1
  478. }
  479. if ( any(is.na(TRIALS)) ) cbind.data.frame(out,SSD=SSD) else
  480. cbind.data.frame(out,SSD=SSD,TRIALS=TRIALS)
  481. }
  482. rWaldssABCD <- function (n, v, B, t0,v0,vT,vF,k=1,minEXG=-Inf,
  483. A=0, tf=0, gf=0, ts = 0,SSD=Inf, TRIALS = NA, staircase=NA)
  484. # Like rWaldss except adds change in v with SSD
  485. # Exponential from v0 to vT and vF
  486. {
  487. if ( length(SSD)==1 ) SSD <- rep(SSD,n)
  488. if ( any(is.na(SSD)) || length(SSD) != n )
  489. stop("SSD cannot have NAs and must be a scalar or same length as n")
  490. n_acc <- ifelse(is.null(dim(v)),length(v),dim(v)[1])
  491. # head start for stop accumulator relative to 0 for go accumulators
  492. t0S <- matrix(rep(c(-t0[1],rep(0,n_acc-1)),length.out=n*n_acc),nrow=n_acc)
  493. # Get index of true and false rates
  494. iT <- c(1:length(v))[v==Inf]
  495. iF <- c(1:length(v))[v==-Inf]
  496. # Get index of stop-signal trials
  497. isSS <- is.finite(SSD)
  498. if (!is.matrix(v)) v <- matrix(rep(v,n),nrow=n_acc)
  499. if (!is.matrix(B)) B <- matrix(rep(B,n),nrow=n_acc)
  500. if (!is.matrix(A)) A <- matrix(rep(A,n),nrow=n_acc)
  501. if ( any(!isSS) ) {
  502. v[iT,!isSS] <- vT
  503. v[iF,!isSS] <- vF
  504. }
  505. if ( !any(is.na(TRIALS)) ) {
  506. if (length(TRIALS)!=n)
  507. stop("TRIALS must have length n")
  508. B[-1,] <- B[-1,] + rep(ts*TRIALS,each=n_acc-1)
  509. }
  510. if ( gf > 0 ) # Setup for GO failure
  511. is.gf <- as.logical(rbinom(length(SSD),1,gf)) else
  512. is.gf <- logical(length(SSD))
  513. if ( all(!is.finite(SSD)) ) { # ALL GO
  514. out <- rWaldRace(n,v=v[-1,,drop=FALSE],B=B[-1,,drop=FALSE],A=A[-1,,drop=FALSE],t0=t0)
  515. out$R <- out$R+1
  516. } else { # SOME STOP
  517. if ( any(is.na(staircase)) ) { # STOP fixed SSD
  518. # Set v
  519. lint <- pmin(k*SSD[isSS],1)
  520. v[iT,isSS] <- v0 + (vT-v0)*lint
  521. v[iF,isSS] <- v0 + (vF-v0)*lint
  522. # add SSD to stop accumulator
  523. t0S[1,] <- t0S[1,] + SSD
  524. out <- rWaldexgRace(n,v=v,B=B,A=A,t0=t0S,a=minEXG)
  525. if ( tf>0 ) {
  526. is.tf <- logical(length(SSD))
  527. is.tf[is.finite(SSD)][as.logical(rbinom(sum(is.finite(SSD)),1,tf))] <- TRUE
  528. if ( any(is.tf) ) {
  529. out[is.tf,] <- rWaldRace(sum(is.tf),v=v[-1,is.tf,drop=FALSE],
  530. B=B[-1,is.tf,drop=FALSE],A=A[-1,is.tf,drop=FALSE],t0=0)
  531. out[is.tf,"R"] <- out[is.tf,"R"]+1
  532. }
  533. }
  534. } else { # STOP, staircase
  535. if ( !is.numeric(staircase) | length(staircase)!=1 )
  536. stop("Staircase must be a numeric vector of length 1 specifying the step.")
  537. SSDi <- SSD[is.finite(SSD)][1] # begining SSD
  538. dt <- v
  539. if ( any(!isSS) )
  540. dt[,!isSS] <- rWaldexgRace(n,v=v[,!isSS,drop=FALSE],
  541. B=B[,!isSS,drop=FALSE],A=A[,!isSS,drop=FALSE],t0=t0S[,!isSS,drop=FALSE],
  542. return.ttf=TRUE,a=minEXG)
  543. # Setup
  544. winner <- numeric(n)
  545. for ( i in c(1:n) ) {
  546. if ( !is.finite(SSD[i]) ) # not staircase
  547. dt[1,i] <- dt[1,i] + SSD[i] else { # staircase
  548. lint <- min(c(k*SSDi,1))
  549. v[iT,i] <- v0 + (vT-v0)*lint
  550. v[iF,i] <- v0 + (vF-v0)*lint
  551. dt[,i] <- rWaldexgRace(1,v=v[,i,drop=FALSE],B=B[,i,drop=FALSE],
  552. A=A[,i,drop=FALSE],t0=t0S[,i,drop=FALSE],return.ttf=TRUE,a=minEXG)
  553. dt[1,i] <- dt[1,i] + SSDi
  554. }
  555. if ( runif(1)<tf ) # Trigger failure
  556. winner[i] <- which.min(dt[2:n_acc,i])+1 else
  557. winner[i] <- which.min(dt[,i])
  558. if (is.gf[i]) winner[i] <- 1
  559. if ( is.finite(SSD[i]) ) { # update staircase
  560. SSD[i] <- SSDi
  561. if ( winner[i]==1 )
  562. SSDi <- SSDi + staircase else
  563. SSDi <- SSDi - staircase
  564. if (SSDi<1e-10) SSDi <- 0
  565. }
  566. }
  567. out <- data.frame(RT=dt[cbind(winner,1:n)],R=winner)
  568. }
  569. out$RT <- out$RT + t0 # Add t0 for go responses
  570. }
  571. # print(out)
  572. out[out$R==1,"RT"] <- NA
  573. if ( gf > 0 ) {
  574. out$RT[is.gf] <- NA
  575. out$R[is.gf] <- 1
  576. }
  577. if ( any(is.na(TRIALS)) ) cbind.data.frame(out,SSD=SSD) else
  578. cbind.data.frame(out,SSD=SSD,TRIALS=TRIALS)
  579. }
  580. n1PDF.Waldss <- function(rt,v,B,t0,A=0,tf=0,gf=0,ts=0,minEXG=-Inf,
  581. SSD=Inf,TRIALS=NA,Si)
  582. # Same as n1Wald except SSD is either a scalar or vector of length(rt)
  583. # stop accumulator must have name "NR". SSD is subtracted stop accumulator time
  584. # and dt=NA done by integration.
  585. #
  586. # tf= probabiliy of trigger failure, where
  587. # L = trigger fail & respond + trigger and respond + trigger and no-response
  588. # = tf*L(N-1)+(1-tf)[L(N)+p(S)],
  589. # L(N-1) = choice race likelihood (no stop accumulator),
  590. # L(N) = full N unit race likelihood given they did respond,
  591. # p(S) probability of stop winning
  592. #
  593. # gf = probabiliy of go failure.
  594. # On go trials: L = go fail (so no response) + go and L above
  595. # L = gf + (1-gf)*[tf*L(N-1)+(1-tf)[L(N)+p(S)]] or similarly
  596. # L = [ p(non-response) ] + [ p(response) ]
  597. # = [ gf + (1-gf)(1-tf)p(S) ] + [ (1-gf){(tf*Ln(n-1) + (1-tf)*L(N))} ]
  598. #
  599. # NB:rt is NOT decision time, but rather full RT as t0 has to be passed
  600. # in order to include properly in cases where RT is NA (i.e., sucessful stop)
  601. {
  602. stopfn <- function(t,vj,Bj,Aj,t0,SSD,Si,minEXG)
  603. {
  604. t0S <- rep(0,length(vj))
  605. t0S[-Si] <- t0S[-Si]+SSD
  606. t0S[Si] <- t0S[Si]+t0
  607. # t0S[-Si] <- t0S[-Si]-t0
  608. # t0S[Si] <- t0S[Si]-SSD
  609. dt <- matrix(rep(t,each=length(vj)),nrow=length(vj))+t0S
  610. i <- c(Si,c(1:length(vj))[-Si])
  611. n1Waldexg(dt[i,,drop=FALSE],v=vj[i],B=Bj[i],A=Aj[i],minEXG=minEXG)
  612. }
  613. # NOTE: t0 is not subtracted when making dt but passed to handle RT=NA case
  614. if ( length(SSD)==1 ) SSD <- rep(SSD,length(rt))
  615. if (length(SSD) != length(rt))
  616. stop("SSD must be a scalar or same length as rt")
  617. n_acc <- ifelse(is.null(dim(v)),length(v),dim(v)[1])
  618. rt <- matrix(rep(rt,each=n_acc),nrow=n_acc)
  619. is.stop <- is.na(rt[1,])
  620. if (!is.matrix(v)) v <- matrix(rep(v,dim(rt)[2]),nrow=n_acc)
  621. if (!is.matrix(B)) B <- matrix(rep(B,dim(rt)[2]),nrow=n_acc)
  622. if (!is.matrix(A)) A <- matrix(rep(A,dim(rt)[2]),nrow=n_acc)
  623. if ( any(is.na(TRIALS)) | ts == 0 ) {
  624. p <- SSD[is.stop]
  625. pj <- c(1:sum(is.stop))[!duplicated(p)] # index of unique SSD
  626. } else {
  627. B[-Si,] <- B[-Si,] + ts*TRIALS
  628. p <- apply(
  629. rbind(B[,is.stop,drop=FALSE],SSD[is.stop]),
  630. 2,paste,collapse="")
  631. pj <- c(1:sum(is.stop))[!duplicated(p)] # index of unique p and SSD
  632. }
  633. if ( any(!is.stop) )
  634. {
  635. rt[Si,!is.stop] <- rt[Si,!is.stop] - SSD[!is.stop]
  636. rt[-Si,!is.stop] <- rt[-Si,!is.stop]-t0
  637. if ( tf > 0 )
  638. {
  639. rt[1,!is.stop] <- (1-gf)*(
  640. tf*n1Wald(rt[-Si,!is.stop,drop=FALSE],v=v[-Si,!is.stop,drop=FALSE],
  641. A=A[-Si,!is.stop,drop=FALSE],B=B[-Si,!is.stop,drop=FALSE]) +
  642. (1-tf)*n1Waldexg(rt[,!is.stop,drop=FALSE],v=v[,!is.stop,drop=FALSE],
  643. minEXG=minEXG[1],
  644. B=B[,!is.stop,drop=FALSE],A=A[,!is.stop,drop=FALSE],Si=Si)
  645. )
  646. } else
  647. rt[1,!is.stop] <- (1-gf)*n1Waldexg(dt=rt[,!is.stop,drop=FALSE],
  648. minEXG=minEXG[1],
  649. v=v[,!is.stop,drop=FALSE],B=B[,!is.stop,drop=FALSE],
  650. A=A[,!is.stop,drop=FALSE],Si=Si)
  651. }
  652. if ( any(is.stop) ) for (j in pj) {
  653. if ( !is.finite(SSD[j]) ) tmp <- 0 else {
  654. if (minEXG==-Inf) lower <- -1 else lower <- pmin(minEXG[1]-t0,0)
  655. tmp <- my.integrate(f=stopfn,lower=minEXG[1]-t0,vj=v[,j],minEXG=minEXG[1],
  656. Bj=B[,j],Aj=A[,j],t0=t0,SSD=SSD[j],Si=Si)
  657. }
  658. rt[1,is.stop][p %in% p[j]] <- gf +(1-gf)*(1-tf)*tmp
  659. }
  660. rt[1,]
  661. }
  662. n1PDF.WaldssABCD <- function(rt,v,B,t0,v0,vT,vF,k=1,
  663. A=0,tf=0,gf=0,ts=0,minEXG=-Inf,SSD=Inf,TRIALS=NA,Si)
  664. # Same as n1PDF.Waldss adds change in v with SSD
  665. # Exponential from v0 to vT and vF
  666. {
  667. stopfn <- function(t,vj,Bj,Aj,t0,SSD,Si,minEXG)
  668. {
  669. t0S <- rep(0,length(vj))
  670. t0S[-Si] <- t0S[-Si]+SSD
  671. t0S[Si] <- t0S[Si]+t0
  672. # t0S[-Si] <- t0S[-Si]-t0
  673. # t0S[Si] <- t0S[Si]-SSD
  674. dt <- matrix(rep(t,each=length(vj)),nrow=length(vj))+t0S
  675. i <- c(Si,c(1:length(vj))[-Si])
  676. n1Waldexg(dt[i,,drop=FALSE],v=vj[i],B=Bj[i],A=Aj[i],minEXG=minEXG)
  677. }
  678. # NOTE: t0 is not subtracted when making dt but passed to handle RT=NA case
  679. if ( length(SSD)==1 ) SSD <- rep(SSD,length(rt))
  680. if (length(SSD) != length(rt))
  681. stop("SSD must be a scalar or same length as rt")
  682. n_acc <- ifelse(is.null(dim(v)),length(v),dim(v)[1])
  683. rt <- matrix(rep(rt,each=n_acc),nrow=n_acc)
  684. is.stop <- is.na(rt[1,])
  685. # Get index of true and false rates
  686. iT <- c(1:length(v))[v==Inf]
  687. iF <- c(1:length(v))[v==-Inf]
  688. # Get index of stop-signal trials
  689. isSS <- is.finite(SSD)
  690. if (!is.matrix(v)) v <- matrix(rep(v,dim(rt)[2]),nrow=n_acc)
  691. if (!is.matrix(B)) B <- matrix(rep(B,dim(rt)[2]),nrow=n_acc)
  692. if (!is.matrix(A)) A <- matrix(rep(A,dim(rt)[2]),nrow=n_acc)
  693. if ( any(!isSS) ) {
  694. v[iT,!isSS] <- vT
  695. v[iF,!isSS] <- vF
  696. }
  697. if ( any(isSS) ) {
  698. lint <- pmin(k*SSD[isSS],1)
  699. v[iT,isSS] <- v0 + (vT-v0)*lint
  700. v[iF,isSS] <- v0 + (vF-v0)*lint
  701. }
  702. if ( any(is.na(TRIALS)) | ts == 0 ) {
  703. p <- SSD[is.stop]
  704. pj <- c(1:sum(is.stop))[!duplicated(p)] # index of unique SSD
  705. } else {
  706. B[-Si,] <- B[-Si,] + ts*TRIALS
  707. p <- apply(
  708. rbind(B[,is.stop,drop=FALSE],SSD[is.stop]),
  709. 2,paste,collapse="")
  710. pj <- c(1:sum(is.stop))[!duplicated(p)] # index of unique p and SSD
  711. }
  712. if ( any(!is.stop) )
  713. {
  714. rt[Si,!is.stop] <- rt[Si,!is.stop] - SSD[!is.stop]
  715. rt[-Si,!is.stop] <- rt[-Si,!is.stop]-t0
  716. if ( tf > 0 )
  717. {
  718. rt[1,!is.stop] <- (1-gf)*(
  719. tf*n1Wald(rt[-Si,!is.stop,drop=FALSE],v=v[-Si,!is.stop,drop=FALSE],
  720. A=A[-Si,!is.stop,drop=FALSE],B=B[-Si,!is.stop,drop=FALSE]) +
  721. (1-tf)*n1Waldexg(rt[,!is.stop,drop=FALSE],v=v[,!is.stop,drop=FALSE],
  722. minEXG=minEXG[1],
  723. B=B[,!is.stop,drop=FALSE],A=A[,!is.stop,drop=FALSE],Si=Si)
  724. )
  725. } else
  726. rt[1,!is.stop] <- (1-gf)*n1Waldexg(dt=rt[,!is.stop,drop=FALSE],
  727. minEXG=minEXG[1],
  728. v=v[,!is.stop,drop=FALSE],B=B[,!is.stop,drop=FALSE],
  729. A=A[,!is.stop,drop=FALSE],Si=Si)
  730. }
  731. if ( any(is.stop) ) for (j in pj) {
  732. if ( !is.finite(SSD[j]) ) tmp <- 0 else {
  733. if (minEXG==-Inf) lower <- -1 else lower <- pmin(minEXG[1]-t0,0)
  734. tmp <- my.integrate(f=stopfn,lower=minEXG[1]-t0,vj=v[,j],minEXG=minEXG[1],
  735. Bj=B[,j],Aj=A[,j],t0=t0,SSD=SSD[j],Si=Si)
  736. }
  737. rt[1,is.stop][p %in% p[j]] <- gf +(1-gf)*(1-tf)*tmp
  738. }
  739. rt[1,]
  740. }
  741. # # VERY EXTENSIVE TESTING WITH Two different SSDs ----
  742. # plot.cell.density <- function(data.cell,C=NA,xlim=NA,limx=c(0,Inf),ymax=NA,lwd=2,
  743. # save.density=FALSE,digits=2,main="",show.mean=FALSE,
  744. # CorrectError.col=c("black","red"),CorrectError.lty=c(1,1))
  745. # # If !is.na(C) plots density for correct and error responses for a data frame
  746. # # with columns R (a factor) and RT, adding a boolean score column for R=C.
  747. # # Otherwise plots each response. Can deal with NA in the RT column, in which
  748. # # case it provides a summary of p(NA)
  749. # {
  750. # if (!is.factor(data.cell$R)) data.cell$R <- factor(data.cell$R)
  751. # if (length(C)==1) C <- rep(C,dim(data.cell)[1])
  752. # p.na <- mean(is.na(data.cell$RT))
  753. # is.in <- !is.na(data.cell$RT)
  754. # is.in[is.in] <- data.cell$RT[is.in]>limx[1] & data.cell$RT[is.in]<limx[2]
  755. # dat <- data.cell[is.in,]
  756. # if ( !any(is.na(C)) ) {
  757. # if ( is.logical(C) & length(C)==dim(data.cell)[1] )
  758. # dat$C <- C[is.in] else dat$C <- dat$R==C[is.in]
  759. # if (length(dat$RT[dat$C])>2)
  760. # dns.correct <- density(dat$RT[dat$C]) else dns.correct <- NULL
  761. # if (length(dat$RT[!dat$C])>2)
  762. # dns.error <- density(dat$RT[!dat$C]) else dns.error <- NULL
  763. # if (is.null(dns.error) & is.null(dns.correct))
  764. # stop("There are no densities to plot")
  765. # acc <- mean(dat$C)
  766. # if (!is.null(dns.correct))
  767. # dns.correct$y <- dns.correct$y*acc*(1-p.na)
  768. # if (!is.null(dns.error))
  769. # dns.error$y <- dns.error$y*(1-acc)*(1-p.na)
  770. # if (is.na(ymax)) ymax <- max(c(dns.correct$y,dns.error$y))
  771. # if (!is.null(dns.correct)) {
  772. # if (any(is.na(xlim))) plot(dns.correct,xlab="RT",ylab="density",ylim=c(0,ymax),main=main,
  773. # col=CorrectError.col[1],lty=CorrectError.lty[1],lwd=lwd) else
  774. # plot(dns.correct,xlab="RT",ylab="density",ylim=c(0,ymax),xlim=xlim,main=main,
  775. # col=CorrectError.col[1],lty=CorrectError.lty[1],lwd=lwd)
  776. # if (!is.null(dns.error)) lines(dns.error,col=CorrectError.col[2],
  777. # lty=CorrectError.lty[2],lwd=lwd)
  778. # } else {
  779. # if (any(is.na(xlim))) plot(dns.error,xlab="RT",ylab="density",ylim=c(0,ymax),main=main,
  780. # col=CorrectError.col[2],lty=CorrectError.lty[2],lwd=lwd) else
  781. # plot(dns.error,xlab="RT",ylab="density",ylim=c(0,ymax),main=main,xlim=xlim,
  782. # col=CorrectError.col[2],lty=CorrectError.lty[2],lwd=lwd)
  783. # if (!is.null(dns.correct)) lines(dns.correct,col=CorrectError.col[1],
  784. # lty=CorrectError.lty[2],lwd=lwd)
  785. # }
  786. # nams <- "Accuracy ="
  787. # ps <- round(acc,digits)
  788. # if (p.na!=0) {
  789. # nams <- c(nams,"p(NA) =")
  790. # ps <- c(ps,round(p.na,digits))
  791. # }
  792. # legend("topright",paste(nams,ps),bty="n")
  793. # legend("topright",xjust=0, inset=c(0,0.1), c("correct","error"),bty="n",
  794. # lty=CorrectError.lty, col=CorrectError.col,lwd=lwd)
  795. # if ( save.density ) list(correct=dns.correct,error=dns.error)
  796. # } else {
  797. # rs <- levels(dat$R)
  798. # dns <- vector(mode="list",length=length(rs))
  799. # names(dns) <- rs
  800. # ps <- table(dat$R)/dim(dat)[1]
  801. # for (i in rs) {
  802. # rt <- dat$RT[dat$R==i]
  803. # if (length(rt)>2) {
  804. # dns[[i]] <- density(rt)
  805. # dns[[i]]$y <- ps[i]*dns[[i]]$y*(1-p.na)
  806. # }
  807. # }
  808. # ymax <- suppressWarnings(max(unlist(lapply(dns,function(x){max(x$y)}))))
  809. # no.dns <- unlist(lapply(dns,is.null))
  810. # if (all(no.dns))
  811. # stop("There are no densities to plot!")
  812. # dns1 <- dns[!no.dns]
  813. # ltys <- c(1:length(dns1))
  814. # plot(dns1[[1]],xlab="RT",ylab="density",ylim=c(0,ymax),lty=ltys[1],
  815. # main=main)
  816. # if (length(dns1)>1) for (i in 2:length(dns1)) lines(dns1[[i]],lty=ltys[i])
  817. # nams <- paste("p(",names(dns1),") =",sep="")
  818. # ps <- round(ps[!no.dns]*(1-p.na),digits)
  819. # if ( p.na!=0 ) {
  820. # nams <- c(nams,"p(NA) =")
  821. # ps <- c(ps,round(p.na,digits))
  822. # lty <- c(ltys,NA)
  823. # }
  824. # legend("topright",paste(nams,ps),lty=ltys,bty="n",lwd=lwd)
  825. # if ( save.density ) dns
  826. # }
  827. # }
  828. #
  829. #
  830. # ########### TWO ACCUMULATOR CASE ----
  831. # {
  832. # n=1e4
  833. # # n=10
  834. # v=c(.5,1); B=c(1,1); A=c(1,1); minEXG=0
  835. # SSD = rep(c(1,10)/10,each=n/2)
  836. #
  837. # # Run one of the follwing two lines
  838. # do.trials=FALSE
  839. # # do.trials = TRUE # requires very differnet plotting check, can be SLOW!
  840. #
  841. # t0=.2
  842. #
  843. # ### RUN ONE OF THE FOLLOWING FOUR LINES
  844. # # Without trigger failure or go failure
  845. # tf=0; gf=0
  846. # # With trigger failure, no go failure
  847. # tf=.1;gf=0
  848. # # Without trigger failure, with go failure
  849. # tf=0; gf=.1
  850. # # With trigger failure and go failure
  851. # tf=.1;gf=.1
  852. #
  853. # if (do.trials) {
  854. # ts=.5; TRIALS=log10(seq(1,10,length.out=n)) # 1..10 natural so 0-1 on log
  855. # TRIALS <- as.vector(t(matrix(TRIALS,nrow=2))) # interleave SSDs
  856. # # Plot slowing in GO (usually nice and linear, up to smooting overfitting)
  857. # sim.go <- rWaldss(n=n,v=v,B=B,A=A,t0=t0,tf=tf,gf=gf,SSD=SSD,TRIALS=TRIALS,ts=ts,minEXG=minEXG)
  858. # is.in <- !is.na(sim.go$RT) # in case go failure
  859. # plot(smooth.spline(TRIALS[is.in],sim.go$RT[is.in]),ylab="Smooth",xlab="TRIALS",type="l")
  860. # } else {TRIALS=NA;ts=0}
  861. #
  862. # # Simulate stop trials
  863. # sim <- rWaldss(n=n,v=v,B=B,A=A,t0=t0,tf=tf,gf=gf,SSD=SSD,TRIALS=TRIALS,ts=ts,minEXG=minEXG)
  864. # # Sucessful inhibition
  865. # tapply(is.na(sim$RT),sim$SSD,mean)
  866. #
  867. #
  868. # # Plot densities
  869. # par(mfrow=c(1,2))
  870. # dns1 <- plot.cell.density(sim[sim$SSD==.1,],limx=c(0,7),save.density=TRUE,main="SSD=.1")
  871. # dns2 <- plot.cell.density(sim[sim$SSD!=.1,],limx=c(0,7),save.density=TRUE,main="SSD=1")
  872. # x1c <- dns1$'2'$x; x2c <- dns2$'2'$x
  873. #
  874. # # Signal respond RT
  875. # dat <- sim; dat <- dat[!is.na(dat$RT),]; dat$R <- factor(as.character(dat$R))
  876. # round(tapply(dat$RT,dat[,c("R","SSD")],mean),2)
  877. #
  878. # if (do.trials) {
  879. # tmp <- n1PDF.Waldss(sim$RT[!is.na(sim$RT)],v=v[2:1],B=B[2:1],A=A[2:1],t0=t0,minEXG=minEXG,
  880. # ts=ts,TRIALS=TRIALS[!is.na(sim$RT)],SSD=SSD[!is.na(sim$RT)],Si=2,tf=tf,gf=gf)
  881. # par(mfrow=c(1,3))
  882. # # red=black?
  883. # plot(x1c,dns1$'2'$y,pch=".",main="SSD=.1",ylab="Density",xlab="RT")
  884. # lines(smooth.spline(sim$RT[!is.na(sim$RT) & SSD==.1],
  885. # tmp[c(SSD==.1)[!is.na(sim$RT)]]),col="red")
  886. # # red=black?
  887. # plot(x2c,dns2$'2'$y,pch=".",main="SSD=1",ylab="Density",xlab="RT")
  888. # lines(smooth.spline(sim$RT[!is.na(sim$RT) & SSD==1],
  889. # tmp[c(SSD==1)[!is.na(sim$RT)]]),col="red")
  890. # # print(tapply(is.na(sim$RT),sim$SSD,mean)) # empirical
  891. # tmp <- n1PDF.Waldss(rep(NA,n),v=v,B=B,A=A,t0=t0,
  892. # SSD=SSD,Si=1,tf=tf,gf=gf,ts=ts,TRIALS=TRIALS)
  893. # # print(mean(tmp[SSD==.1]))
  894. # # print(mean(tmp[SSD==1]))
  895. # plot(TRIALS,tmp,pch=".",xlab="TRIALS",ylab="p(NA)",ylim=c(0,1))
  896. # lines(smooth.spline(TRIALS[SSD==.1],as.numeric(is.na(sim$RT)[SSD==.1])),col="red")
  897. # lines(smooth.spline(TRIALS[SSD==1],as.numeric(is.na(sim$RT)[SSD==1])),col="red")
  898. # } else {
  899. # # Save simulated densities
  900. # r1 <- c(2,1)
  901. # d.r1 <- n1PDF.Waldss(rt=c(x1c,x2c),v=v[r1],B=B[r1],A=A[r1],t0=t0,minEXG=minEXG,
  902. # SSD=c(rep(.1,length(x1c)),rep(1,length(x2c))),Si=2,tf=tf,gf=gf)
  903. # # Plot simulated (black) and theoretical (red) densities
  904. # par(mfrow=c(1,2))
  905. # # red=black?
  906. # plot(x1c,dns1$'2'$y,type="l",main="SSD=.1",ylab="Density",xlab="RT",
  907. # ylim=c(0,max(dns1$'2'$y)))
  908. # lines(x1c,d.r1[1:length(x1c)],col="red")
  909. # # red=black?
  910. # plot(x2c,dns2$'2'$y,type="l",main="SSD=1",ylab="Density",xlab="RT",
  911. # ylim=c(0,max(dns2$'2'$y)))
  912. # lines(x2c,d.r1[(length(x2c)+1):(2*length(x2c))],col="red")
  913. #
  914. # # # p(Stop check)
  915. # # print(tapply(is.na(sim$RT),sim$SSD,mean)) # empirical
  916. # # print(n1PDF.Waldss(NA,v=v,A=A,B=B,t0=t0,SSD=.1,Si=1,tf=tf,gf=gf,minEXG=minEXG))
  917. # # print(n1PDF.Waldss(NA,v=v,A=A,B=B,t0=t0,SSD=1,Si=1,tf=tf,gf=gf,minEXG=minEXG))
  918. # }
  919. #
  920. # }
  921. #
  922. # ########### THREE ACCUMULATOR CASE ----
  923. # {
  924. # n=1e5
  925. # SSDs = c(1,10)/10
  926. # v=c(1,.75,.25); B=c(1,1,1); A=c(1,1,1); minEXG=0
  927. # SSD = rep(SSDs,each=n/2)
  928. #
  929. # do.trials=FALSE
  930. # do.trials = TRUE # requires very differnet plotting check, can be SLOW!
  931. #
  932. # t0=.2
  933. # ### RUN ONE OF THE FOLLOWING FOUR LINES
  934. # # Without trigger failure or go failure
  935. # tf=0; gf=0
  936. # # With trigger failure, no go failure
  937. # tf=.1;gf=0
  938. # # Without trigger failure, with go failure
  939. # tf=0; gf=.1
  940. # # With trigger failure and go failure
  941. # tf=.1;gf=.1
  942. #
  943. # if (do.trials) {
  944. # ts=.5; TRIALS=log10(seq(1,10,length.out=n)) # 1..10 natural so 0-1 on log
  945. # TRIALS <- as.vector(t(matrix(TRIALS,nrow=2))) # interleave SSDs
  946. # # Plot slowing in GO (usually nice and linear, up to smooting overfitting)
  947. # sim.go <- rWaldss(n=n,v=v,B=B,A=A,t0=t0,tf=tf,gf=gf,TRIALS=TRIALS,ts=ts,minEXG=minEXG)
  948. # is.in <- !is.na(sim.go$RT) # in case go failure
  949. # plot(smooth.spline(TRIALS[is.in],sim.go$RT[is.in]),ylab="Smooth",xlab="TRIALS",type="l")
  950. # } else {TRIALS=NA;ts=0}
  951. #
  952. # # Simulate stop trials
  953. # par(mfrow=c(1,3)); xlim=c(0,1)
  954. # simgo <- rWaldss(n=n,v=v,B=B,A=A,t0=t0,tf=tf,gf=gf,TRIALS=TRIALS,ts=ts,SSD=Inf,minEXG=minEXG)
  955. # plot.cell.density(simgo,main="Go",xlim=xlim)
  956. # sim <- rWaldss(n=n,v=v,B=B,A=A,t0=t0,tf=tf,gf=gf,TRIALS=TRIALS,ts=ts,SSD=SSD,minEXG=minEXG)
  957. # # Sucessful inhibition
  958. # tapply(is.na(sim$RT),sim$SSD,mean)
  959. # dns1 <- plot.cell.density(sim[sim$SSD==SSDs[1],],limx=c(0,7),save.density=TRUE,main="SSD=.1",xlim=xlim)
  960. # dns2 <- plot.cell.density(sim[sim$SSD!=SSDs[1],],limx=c(0,7),save.density=TRUE,main="SSD=1",xlim=xlim)
  961. # x1c <- dns1$'2'$x; x2c <- dns2$'2'$x
  962. # x1e <- dns1$'3'$x; x2e <- dns2$'3'$x
  963. #
  964. # # Signal respond RT
  965. # dat <- sim; dat <- dat[!is.na(dat$RT),]; dat$R <- factor(as.character(dat$R))
  966. # round(tapply(dat$RT,dat[,c("R","SSD")],mean),2)
  967. #
  968. # if (do.trials) {
  969. # r1 <- c(2,1,3)
  970. # is.in1 <- !is.na(sim$RT) & sim$R==2
  971. # d.r1 <- n1PDF.Waldss(sim$RT[is.in1],v=v[r1],ts=ts,TRIALS=TRIALS[is.in1],
  972. # B=B[r1],A=A[r1],t0=t0,SSD=SSD[is.in1],Si=2,tf=tf,gf=gf,minEXG=minEXG)
  973. # r2 <- c(3,1,2)
  974. # is.in2 <- !is.na(sim$RT) & sim$R==3
  975. # d.r2 <- n1PDF.Waldss(sim$RT[is.in2],v=v[r2],ts=ts,TRIALS=TRIALS[is.in2],
  976. # B=B[r2],A=A[r2],t0,SSD=SSD[is.in2],Si=2,tf=tf,gf=gf,minEXG=minEXG)
  977. # par(mfrow=c(1,3))
  978. # # red=black?
  979. # plot(x1c,dns1$'2'$y,pch=".",main="SSD=.1",ylab="Density",xlab="RT",type="l")
  980. # lines(x1e,dns1$'3'$y,lty=2)
  981. # lines(smooth.spline(sim$RT[is.in1 & sim$SSD==.1],
  982. # d.r1[c(sim$SSD==.1)[is.in1]]),col="red")
  983. # lines(smooth.spline(sim$RT[is.in2 & sim$SSD==.1],d.r2[c(sim$SSD==.1)[is.in2]]),
  984. # lty=2,col="red")
  985. # # red=black?
  986. # plot(x2c,dns2$'2'$y,pch=".",main="SSD=1",ylab="Density",xlab="RT",type="l")
  987. # lines(x2e,dns2$'3'$y,lty=2)
  988. # lines(smooth.spline(sim$RT[is.in1 & sim$SSD==1],
  989. # d.r1[c(sim$SSD==1)[is.in1]]),col="red")
  990. # lines(smooth.spline(sim$RT[is.in2 & sim$SSD==1],
  991. # d.r2[c(sim$SSD==1)[is.in2]]),col="red",lty=2)
  992. #
  993. # # print(tapply(is.na(sim$RT),sim$SSD,mean)) # empirical
  994. # tmp <- n1PDF.Waldss(rep(NA,n),v=v,A=A,B=B,t0=t0,SSD=SSD,Si=1,tf=tf,gf=gf,ts=ts,
  995. # TRIALS=TRIALS,minEXG=minEXG)
  996. # # print(mean(tmp[SSD==.1]))
  997. # # print(mean(tmp[SSD==1]))
  998. # plot(TRIALS,tmp,pch=".",xlab="TRIALS",ylab="p(NA)",ylim=c(0,1))
  999. # lines(smooth.spline(TRIALS[SSD==.1],as.numeric(is.na(sim$RT)[SSD==.1])),col="red")
  1000. # lines(smooth.spline(TRIALS[SSD==1],as.numeric(is.na(sim$RT)[SSD==1])),col="red")
  1001. # } else {
  1002. # # Save simulated densities
  1003. # r1 <- c(2,1,3)
  1004. # d.r1 <- n1PDF.Waldss(rt=c(x1c,x2c),v=v[r1],B=B[r1],A=A[r1],t0=t0,minEXG=minEXG,
  1005. # SSD=c(rep(.1,length(x1c)),rep(1,length(x2c))),Si=2,tf=tf,gf=gf)
  1006. # r2 <- c(3,1,2)
  1007. # d.r2 <- n1PDF.Waldss(rt=c(x1e,x2e),v=v[r2],B=B[r2],A=A[r2],t0=t0,minEXG=minEXG,
  1008. # SSD=c(rep(.1,length(x1e)),rep(1,length(x2e))),Si=2,tf=tf,gf=gf)
  1009. # # Plot simulated (black) and theoretical (red) densities
  1010. # par(mfrow=c(1,2))
  1011. # # red=black?
  1012. # plot(x1c,dns1$'2'$y,type="l",main="SSD=.1",ylab="Density",xlab="RT",
  1013. # ylim=c(0,max(dns1$'2'$y)))
  1014. # lines(x1c,d.r1[1:length(x1c)],col="red")
  1015. # lines(x1e,dns1$'3'$y,lty=2)
  1016. # lines(x1e,d.r2[1:length(x1e)],col="red",lty=2)
  1017. # # red=black?
  1018. # plot(x2c,dns2$'2'$y,type="l",main="SSD=1",ylab="Density",xlab="RT",
  1019. # ylim=c(0,max(dns2$'2'$y)))
  1020. # lines(x2c,d.r1[(length(x2c)+1):(2*length(x2c))],col="red")
  1021. # lines(x2e,dns2$'3'$y,lty=2)
  1022. # lines(x2e,d.r2[(length(x2e)+1):(2*length(x2e))],col="red",lty=2)
  1023. #
  1024. # # # p(Stop check)
  1025. # # print(tapply(is.na(sim$RT),sim$SSD,mean)) # empirical
  1026. # # print(n1PDF.Waldss(NA,v=v,B=B,A=A,t0=t0,SSD=.1,Si=1,tf=tf,gf=gf))
  1027. # # print(n1PDF.Waldss(NA,v=v,B=B,A=A,t0=t0,SSD=1,Si=1,tf=tf,gf=gf))
  1028. # }
  1029. # }

dists.R, no license · at the source

Overview

Authors: Yihe Weng1, Rory Boyle1, Chi Tak Lee1, Declan Quinn1, Clodagh Earley1, Maike Splittgerber1, Lili Zhang2, Luisa Franzen1,3, Tobias Banaschewski4,5, Arun L. W. Bokde6, Sylvane Desrivières7, Herta Flor8,9, Antoine Grigis10, Hugh Garavan11, Penny Gowland12, Andreas Heinz13,14,15, Rüdiger Brühl16, Jean-Luc Martinot17,18, Marie-Laure Paillère Martinot17,19, Eric Artiges17,18
and 13 other authorsJane McGrath6, Frauke Nees20, Dimitri Papadopoulos Orfanos9, Luise Poustka21, Nathalie Holz4,5, Sarah Hohmann4,5,22, Michael N. Smolka15, Nilakshi Vaidya23, Gunter Schumann23,24,25, Henrik Walter26, Alexander Weigard27,28, Robert Whelan1,28, IMAGEN Consortium
28 affiliations
  1. School of Psychology and Global Brain Health Institute, Trinity College Dublin, Dublin, Ireland
  2. School of Computing, Dublin City University, Dublin, Ireland
  3. Faculty of Psychology and Neuroscience, Maastricht University, Maastricht, Netherlands
  4. Department of Child and Adolescent Psychiatry and Psychotherapy, Central Institute of Mental Health, Medical Faculty Mannheim, Heidelberg University, Square J5, 68159 Mannheim, Germany
  5. German Center for Mental Health (DZPG), Partner Site Mannheim-Heidelberg-Ulm, Heidelberg, Germany
  6. Discipline of Psychiatry, School of Medicine and Trinity College Institute of Neuroscience, Trinity College Dublin, Dublin, Ireland
  7. Social, Genetic and Developmental Psychiatry Centre, Institute of Psychiatry, Psychology & Neuroscience, King’s College London, London, UK
  8. Institute of Cognitive and Clinical Neuroscience, Central Institute of Mental Health, Medical Faculty Mannheim, Heidelberg University, Square J5, Mannheim, Germany
  9. Department of Psychology, School of Social Sciences, University of Mannheim, 68131 Mannheim, Germany
  10. NeuroSpin, CEA, Université Paris-Saclay, F-91191 Gif-sur-Yvette, France
  11. Departments of Psychiatry and Psychology, University of Vermont, 05405 Burlington, Vermont, USA
  12. Sir Peter Mansfield Imaging Centre School of Physics and Astronomy, University of Nottingham, University Park, Nottingham, UK
  13. Department of Psychiatry and Psychotherapy, University of Tübingen, Tübingen, Germany
  14. German Center for Mental Health (DZPG), Site Tübingen, Germany
  15. Department of Psychiatry and Psychotherapy, Technische Universität Dresden, Dresden, Germany
  16. Physikalisch-Technische Bundesanstalt (PTB), Braunschweig and Berlin, Berlin, Germany
  17. INSERM U1299 “Developmental Trajectories in Psychiatry & Addictology”; University Paris-Saclay, Ecole Normale Supérieure Paris-Saclay, Mathematics department, Centre Borelli CNRS UMR9010, Gif-sur-Yvette, France
  18. Department of Psychiatry, LabD-Psy, Barthélémy Durand Hospital, Etampes, France
  19. AP-HP. Sorbonne Université, Department of Child and Adolescent Psychiatry, Pitié-Salpêtrière Hospital, Paris, France
  20. Institute of Medical Psychology, Ludwig-Maximilians-Universität (LMU) in Munich, Munich, Germany
  21. Department of Child and Adolescent Psychiatry, Center for Psychosocial Medicine, University Hospital Heidelberg, Heidelberg, Germany
  22. Department of Child and Adolescent Psychiatry, Psychotherapy and Psychosomatics, University Medical Centre Hamburg-Eppendorf, Hamburg, Germany
  23. Centre for Population Neuroscience and Stratified Medicine (PONS), Department of Psychiatry and Psychotherapy, Charité Universitätsmedizin Berlin, Berlin, Germany
  24. Centre for Population Neuroscience and Stratified Medicine (PONS), Institute for Science and Technology of Brain-Inspired Intelligence and National Centre for Neurological Disorders, Huashan Hospital, Fudan University, Shanghai, China
  25. German Center for Mental Health (DZPG), Site Berlin-, Potsdam, Germany
  26. Department of Psychiatry and Psychotherapy CCM, Charité – Universitätsmedizin Berlin, corporate member of Freie Universität Berlin, Humboldt-Universität zu Berlin, and Berlin Institute of Health, Berlin, Germany
  27. Department of Psychiatry and Addiction Center, University of Michigan, 4250 Plymouth Rd, Ann Arbor, MI 48109, USA
  28. These authors contributed equally: Alexander Weigard, Robert Whelan
Dates: published online 22 April 2026; in print April 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41386-026-02401-6 · PMID 42020764 · PMCID PMC13592875 · OpenAlex W7155221093
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: other condition (population)
Methods: Statistics, Machine learning, Connectivity, fMRI & imaging
Topic: Functional Brain Connectivity Studies (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: Agence Nationale de la Recherche (French National Research Agency) (AAPG2019 - GeBra, ANR-12-SAMA-0004); NIDA NIH HHS (K23 DA051561, R01 DA049238); NIA NIH HHS (R56 AG058854); NIMH NIH HHS (R01 MH085772); NIBIB NIH HHS (U54 EB020403); Science Foundation Ireland (SFI) (16/ERCD/3797)
Citations: cited by 1 paper (Europe PMC); 71 references in the paper

Abstract

Poor inhibitory control and decision-making are often considered as risks for substance use and other adverse psychiatric outcomes. The Stop-Signal Task (SST) is a widely used protocol, from which inhibitory control is indexed by stop signal reaction time (SSRT). However, heretofore models of SSRT may be too simplistic to capture complex processes underlying task performance. In contrast, the Racing Diffusion Ex-Gaussian ABCD (RDEX-ABCD) model provides a more mechanistic framework, capturing both inhibitory control and task-general decision-making processes during the SST. Here, we applied the RDEX-ABCD model to SST data from the IMAGEN cohort (n > 1000) at ages 19 and 23, and examined model parameters in relation to substance use via Elastic Net regression. Connectome-based predictive modeling was then performed to identify brain networks predicting parameters, and the association between these networks and substance use was examined. We found that parameters indexing inhibitory control had no associations with substance use and were only weakly associated with brain connectivity. In contrast, parameters reflecting general decision-making processes – such as efficiency of evidence accumulation, decision threshold (response caution), probability of go failure – and their associated brain activity were significant predictors of cannabis and cigarette use. These findings suggested that efficiency of evidence accumulation, a neurocognitive mechanism that facilitates adaptive decision making across many contexts, emerged as a robust predictor of substance use vulnerability. Overall, general decision-making mechanisms may act as more reliable indicators of vulnerability to substance use than the conventional inhibitory control measures.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 3 matches between paragraphs and lines of code.

OSF 2h8a7

License: none: the authors keep all their rights
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Languages: R (27), Jupyter (1)
Size: 38 files, 28 scripts
Software Heritage: not checked
Found in: the text, “RDEX-ABCD model evaluation and estimation”
Holds: README, 1 notebook
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: tidyverse (2 files), ggplot2 (1 file), NumPy (1 file), pandas (1 file)
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
  • 29 September 2026: the link answers (HTTP 200)
28 files
At the source: osf.io/2h8a7/

OSF 6ejpd

License: none: the authors keep all their rights
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Size: 0 files, 0 scripts
Software Heritage: not checked
Found in: “DATA AVAILABILITY”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 29 September 2026: the link answers (HTTP 200)
  • 29 September 2026: the link answers (HTTP 200)
At the source: osf.io/6ejpd/

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 28 scripts, each with its path and the digest of its content;
  • 3 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability

IMAGEN data are available from a dedicated database: https://imagen2.cea.fr. Due to participant consent restrictions, IMAGEN data cannot be made fully open access. Code for CPM analysis is available at https://osf.io/6ejpd/.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 29 September 2026: the first record

Recorded: type, language, journal, pages, dates, 33 authors, 6 funders, 62 references.

Cite

This paper

Weng, Y., Boyle, R., Lee, C. T., Quinn, D., Earley, C., Splittgerber, M., Zhang, L., Franzen, L., Banaschewski, T., Bokde, A. L. W., Desrivières, S., Flor, H., Grigis, A., Garavan, H., Gowland, P., Heinz, A., Brühl, R., Martinot, J.-L., Martinot, M.-L. P., . . . IMAGEN Consortium. (2026). Model-based analysis of stop-signal data reveals robust neural and clinical correlates of evidence accumulation but not inhibition. Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology, 10.1038/s41386-026-02401-6. https://doi.org/10.1038/s41386-026-02401-6

BibTeX

@article{weng2026model,
author = {Weng, Yihe and Boyle, Rory and Lee, Chi Tak and Quinn, Declan and Earley, Clodagh and Splittgerber, Maike and Zhang, Lili and Franzen, Luisa and Banaschewski, Tobias and Bokde, Arun L. W. and Desrivières, Sylvane and Flor, Herta and Grigis, Antoine and Garavan, Hugh and Gowland, Penny and Heinz, Andreas and Brühl, Rüdiger and Martinot, Jean-Luc and Martinot, Marie-Laure Paillère and Artiges, Eric and McGrath, Jane and Nees, Frauke and Orfanos, Dimitri Papadopoulos and Poustka, Luise and Holz, Nathalie and Hohmann, Sarah and Smolka, Michael N. and Vaidya, Nilakshi and Schumann, Gunter and Walter, Henrik and Weigard, Alexander and Whelan, Robert and {IMAGEN Consortium}},
title = {{Model-based analysis of stop-signal data reveals robust neural and clinical correlates of evidence accumulation but not inhibition}},
journal = {Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology},
year = {2026},
month = apr,
pages = {10.1038/s41386--026--02401--6},
publisher = {Nature Publishing Group},
issn = {0893-133X},
doi = {10.1038/s41386-026-02401-6},
url = {https://doi.org/10.1038/s41386-026-02401-6},
pmid = {42020764},
pmcid = {PMC13592875}
}

RIS

TY - JOUR
AU - Weng, Yihe
AU - Boyle, Rory
AU - Lee, Chi Tak
AU - Quinn, Declan
AU - Earley, Clodagh
AU - Splittgerber, Maike
AU - Zhang, Lili
AU - Franzen, Luisa
AU - Banaschewski, Tobias
AU - Bokde, Arun L. W.
AU - Desrivières, Sylvane
AU - Flor, Herta
AU - Grigis, Antoine
AU - Garavan, Hugh
AU - Gowland, Penny
AU - Heinz, Andreas
AU - Brühl, Rüdiger
AU - Martinot, Jean-Luc
AU - Martinot, Marie-Laure Paillère
AU - Artiges, Eric
AU - McGrath, Jane
AU - Nees, Frauke
AU - Orfanos, Dimitri Papadopoulos
AU - Poustka, Luise
AU - Holz, Nathalie
AU - Hohmann, Sarah
AU - Smolka, Michael N.
AU - Vaidya, Nilakshi
AU - Schumann, Gunter
AU - Walter, Henrik
AU - Weigard, Alexander
AU - Whelan, Robert
AU - IMAGEN Consortium
TI - Model-based analysis of stop-signal data reveals robust neural and clinical correlates of evidence accumulation but not inhibition
T2 - Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology
J2 - Neuropsychopharmacology
PY - 2026
DA - 2026/04/22
SP - 10.1038/s41386
EP - 026-02401-6
SN - 0893-133X
PB - Nature Publishing Group
DO - 10.1038/s41386-026-02401-6
UR - https://doi.org/10.1038/s41386-026-02401-6
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41386-026-02401-6",
"type": "article-journal",
"title": "Model-based analysis of stop-signal data reveals robust neural and clinical correlates of evidence accumulation but not inhibition",
"container-title": "Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology",
"author": [
{
"family": "Weng",
"given": "Yihe"
},
{
"family": "Boyle",
"given": "Rory"
},
{
"family": "Lee",
"given": "Chi Tak"
},
{
"family": "Quinn",
"given": "Declan"
},
{
"family": "Earley",
"given": "Clodagh"
},
{
"family": "Splittgerber",
"given": "Maike"
},
{
"family": "Zhang",
"given": "Lili"
},
{
"family": "Franzen",
"given": "Luisa"
},
{
"family": "Banaschewski",
"given": "Tobias"
},
{
"family": "Bokde",
"given": "Arun L. W."
},
{
"family": "Desrivières",
"given": "Sylvane"
},
{
"family": "Flor",
"given": "Herta"
},
{
"family": "Grigis",
"given": "Antoine"
},
{
"family": "Garavan",
"given": "Hugh"
},
{
"family": "Gowland",
"given": "Penny"
},
{
"family": "Heinz",
"given": "Andreas"
},
{
"family": "Brühl",
"given": "Rüdiger"
},
{
"family": "Martinot",
"given": "Jean-Luc"
},
{
"family": "Martinot",
"given": "Marie-Laure Paillère"
},
{
"family": "Artiges",
"given": "Eric"
},
{
"family": "McGrath",
"given": "Jane"
},
{
"family": "Nees",
"given": "Frauke"
},
{
"family": "Orfanos",
"given": "Dimitri Papadopoulos"
},
{
"family": "Poustka",
"given": "Luise"
},
{
"family": "Holz",
"given": "Nathalie"
},
{
"family": "Hohmann",
"given": "Sarah"
},
{
"family": "Smolka",
"given": "Michael N."
},
{
"family": "Vaidya",
"given": "Nilakshi"
},
{
"family": "Schumann",
"given": "Gunter"
},
{
"family": "Walter",
"given": "Henrik"
},
{
"family": "Weigard",
"given": "Alexander"
},
{
"family": "Whelan",
"given": "Robert"
},
{
"literal": "IMAGEN Consortium"
}
],
"container-title-short": "Neuropsychopharmacology",
"page": "10.1038/s41386-026-02401-6",
"DOI": "10.1038/s41386-026-02401-6",
"PMID": "42020764",
"PMCID": "PMC13592875",
"ISSN": "0893-133X",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41386-026-02401-6",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
22
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1126/sciadv.aed0772 [code]
Deep learning reveals a neurocomputational mechanism predicting depression risk in adolescents.
Journal: Science advances
In common: ggplot2, tidyverse, 16 authors
[2] doi:10.1038/s41398-026-04010-9 [code]
Bullying victimization and brain development: a longitudinal structural magnetic resonance imaging study from adolescence to early adulthood.
Journal: Translational psychiatry
In common: ggplot2, tidyverse, 16 authors
[3] doi:10.1038/s41398-026-04114-2 [code]
Plasma Glial Fibrillary Acidic Protein (GFAP) shows age-dependent associations with externalizing psychopathology and atypical brain connectivity.
Journal: Translational psychiatry
In common: ggplot2, tidyverse, pandas, 1 other tool, 1 reference, 3 authors
[4] doi:10.1523/eneuro.0370-25.2026 [code]
Pretraining for Large-Scale Functional Connectome Fingerprinting Supports Generalization and Transfer Learning in Functional Neuroimaging.
Journal: eNeuro
In common: pandas, NumPy, 5 references
[5] doi:10.1038/s41467-026-71404-0 [code]
Nonergodicity and Simpson's paradox in neurocognitive dynamics of cognitive control.
Journal: Nature communications
In common: pandas, NumPy, 4 references
[6] doi:10.1016/j.isci.2026.116034
Distinct temporal patterns of beta bursts differentiate successful and failed movement cancellation.
Journal: iScience
In common: 4 references
[7] doi:10.1111/psyp.70397 [code]
Cortical Contributions to Attentional Orienting and Response Cancellation in Action Stopping.
Journal: Psychophysiology
In common: pandas, NumPy, 3 references
[8] doi:10.1017/s0033291726104103 [code]
Linking brain structure to stress reactivity: cingulate surface area predicts acute cortisol responses.
Journal: Psychological medicine
In common: pandas, NumPy, author Henrik Walter
[9] doi:10.1093/braincomms/fcag045 [code]
Examining neuroimaging biomarkers, plasma biomarkers and cognitive functions in patients with recovered COVID-19 infection: a multicentre study using 7T MRI.
Journal: Brain communications
In common: NumPy, other condition, author Penny Gowland
[10] doi:10.1038/s41398-026-04140-0 [code]
Predicting stress response trajectories: Differential contributions of limbic and prefrontal regions to cortisol and affective responses.
Journal: Translational psychiatry
In common: tidyverse, author Henrik Walter

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.