//These default search parameters may be changed by assigning new values to the variables BS_SPIKES_MIN = 3 BS_SI_MIN = 3 objref facTable facTable = new Vector(171) facTable.x(0) = 1 tmp = 1 for i=1,170 { tmp = tmp*i facTable.x(i) = tmp } func factorial() { //$1:n if ($1 > 170) { // print "factorial over limit ", $1 return facTable.x(170) } else { return facTable.x($1) } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// proc surpriseIndex() {local i,j,tmp,SI_MAX,lambda,explambda,poisscdf //$1:nSpikes, $2:timeInterval, $3:meanIsi, $&4:si, $&5:prb //////////////// //function [si prb]=surpriseIndex(nSpikes, timeInterval, meanIsi) SI_MAX = 100 prbMIN = exp(-SI_MAX) //prb = 1 - poisscdf(nSpikes-1, timeInterval/ meanIsi); lambda = $2/$3 if (lambda < 0) { print "surpriseIndex() lambda < 0" explambda = 0 } else { explambda = exp(-lambda) } //poisscdf = 0 //for i=0,$1-1 { // poisscdf = poisscdf + (explambda*lambda^i)/factorial(i) //} poisscdf = explambda tmp = explambda for i=1,$1-1 { tmp = tmp*(lambda/i) poisscdf = poisscdf + tmp } $&5 = 1 - poisscdf if ($&5 <= prbMIN) { $&4 = SI_MAX } else { $&4 = -log($&5) } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// func findBurst() {local i,j,isiMean,bStart,bEnd,numSpikes,siMax,found,si,prb localobj x,ebIsi,b0bf //$o1:x, $o2:ebIsi, $3:isiMean, $4:bStart, $o5:b0bf //////////////// //function [b_0, b_f]=findBurst(x, params, ebIsi, bStart) x = $o1 ebIsi = $o2 isiMean = $3 bStart = $4 b0bf = $o5 b0bf.x(0) = bStart b0bf.x(1) = bStart bEnd = ebIsi.indwhere(">", bStart) if (bEnd < 0) { bEnd = x.size()-1 } else { bEnd = ebIsi.x(bEnd) } //reject this burst segment if not enough spikes numSpikes = bEnd - bStart + 1 if (numSpikes < BS_SPIKES_MIN) { b0bf.x(1) = b0bf.x(0) return -1 } //find least probable (highest surprise) string of spikes in burst segment siMax = 0 numSpikes = 0 for i=bStart,bEnd-BS_SPIKES_MIN+1 { for j=i+BS_SPIKES_MIN-1,bEnd { numIsi = j - i dur = x.x(j) - x.x(i) surpriseIndex(numIsi, dur, isiMean, &si, &prb) if (si > siMax) { found = 1 } else { if ((si == siMax) && ((j-i+1) > numSpikes)) { found = 1 } else { found = 0 } } if (found > 0) { b0bf.x(0) = i b0bf.x(1) = j siMax = si numSpikes = j - i + 1 } } } if (siMax < BS_SI_MIN) { //No burst above surprise minimum in current burst segment b0bf.x(1) = b0bf.x(0) return -1 } return 1 } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// proc burstSearch() {local isiMean,flag,tmp,n localobj x,xIsi,res,bIsi,ebIsi,b0bf //$o1:x, $o2:xIsi, $o3:result //////////////// //function res=burstSearch(x, xIsi, isiMean) x = $o1 xIsi = $o2 res = $o3 bIsi = new Vector() ebIsi = new Vector() b0bf = new Vector(2,0) res.resize(1,1) res.x[0][0] = 0 if (xIsi.size > 0) { isiMean = xIsi.mean() } else { print "burstSearch xIsi.size() == 0" return } bIsi.indvwhere(xIsi, "()", 0, isiMean) ebIsi.indvwhere(xIsi, "[)", isiMean, 1e9) if (bIsi.size() > 0) { nextBurst = bIsi.x(0) flag = 1 } else { flag = 0 } //keep finding bursts until starting points are exhausted while (flag > 0) { tmp = findBurst(x, ebIsi, isiMean, nextBurst, b0bf) if (tmp > 0) { n = res.nrow if (res.x[0][0] == 0) { res.resize(1,2) } else { n = n + 1 res.resize(n, 2) } res.x[n-1][0] = b0bf.x(0) res.x[n-1][1] = b0bf.x(1) } //next potential burst start tmp = ebIsi.indwhere(">=", b0bf.x(1)) if (tmp >= 0) { tmp = ebIsi.x(tmp) tmp = bIsi.indwhere(">", tmp) if (tmp >= 0) { nextBurst = bIsi.x(tmp) } else { nextBurst = -1 } } else { nextBurst = -1 } flag = (nextBurst > 0) } return }