// calcisilag.hoc
// Olfactory bulb network model: calculate inter-spike interval
// : and lag time statistics
// Andrew Davison, The Babraham Institute, 2000.
/* The following procedures are defined for writing results to file
* fileroot is the filename root. A suffix will be added to
* this, e.g. fileroot.synch for print_si().
* i,j are the mitral cell indices
*
* print_smooth_hist(variance,fileroot)
* print_gran_smooth_hist(variance,fileroot)
* print_spiketimes(i,j,fileroot)
* print_raster(fileroot)
* print_gran_raster(fileroot)
* print_isis(i,j,fileroot)
* print_isi_stats(fileroot)
* print_lags(i,j,fileroot)
* print_si(fileroot)
*/
// Variables used in this file
objref work, work2, outputarray, isi, lags, hist
work = new Vector()
work2 = new Vector()
outputarray = new Matrix(nmitx,nmity)
isi = new Vector()
lags = new Vector()
// Procedures for processing spike times -------------------------------
proc calc_isis() { local i,j,k,n // 3 args - indices of mitral cell, transient time
if ($1 > nmitx || $2 > nmity) {
print "Sorry - index out of range. Please try again."
return
}
i = int($1)
j = int($2)
isi.resize(0)
n = mit[i][j].spiketimes.size()
if (n > 1) {
for k = 1,n-1 {
if (mit[i][j].spiketimes.x[k-1] > $3) {
isi.append(mit[i][j].spiketimes.x[k]-mit[i][j].spiketimes.x[k-1])
}
}
}
}
proc calc_gran_isis() { local i,j,k,n // 3 args - indices of granule cell, transient time
if ($1 > ngranx || $2 > ngrany) {
print "Sorry - index out of range. Please try again."
return
}
i = int($1)
j = int($2)
isi.resize(0)
n = gran[i][j].spiketimes.size()
if (n > 1) {
for k = 1,n-1 {
if (gran[i][j].spiketimes.x[k-1] > $3) {
isi.append(gran[i][j].spiketimes.x[k]-gran[i][j].spiketimes.x[k-1])
}
}
}
}
func minisi() { local i,j,min // find shortest mean ISI
min = 1e6
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
calc_isis(i,j,ttrans)
if (isi.size() > 0) {
if (isi.mean() < min) { min = isi.mean() }
}
}
}
return min
}
proc rate_array() { local i,j
for i = 0,nmitx-1 {
for j = 0, nmity-1 {
calc_isis(i,j,ttrans)
if (isi.size() > 0) {
outputarray.x[i][j] = 1000/isi.mean()
} else {
outputarray.x[i][j] = 0
}
}
}
print "Max: ",arraymax(outputarray)
outputarray.muls(1/arraymax(outputarray))
}
proc calc_lags() { local i1,j1,i2,j2,k,minidx,min // 5 args - indices of mitral cells, transient time
if ($1 > nmitx || $2 > nmity || $3 > nmitx || $4 > nmity) {
print "Sorry - index out of range. Please try again."
return
}
i1 = int($1)
j1 = int($2)
i2 = int($3)
j2 = int($4)
lags.resize(0)
// for each spiketime in cell 1, find closest spike in cell 2
// Note: first and last spikes ignored since can't calculate previous ISI
if (mit[i2][j2].spiketimes.size > 0) {
for k = 1,mit[i1][j1].spiketimes.size()-2 {
if (mit[i1][j1].spiketimes.x[k] > $5) {
work = mit[i2][j2].spiketimes.c.add(-mit[i1][j1].spiketimes.x[k])
minidx = work.c.abs.min_ind()
min = work.x[minidx]
isiprev = mit[i1][j1].spiketimes.x[k-1]-mit[i1][j1].spiketimes.x[k]
isinext = mit[i1][j1].spiketimes.x[k+1]-mit[i1][j1].spiketimes.x[k]
if (min > isiprev/2 && min < isinext/2) {
lags.append(min)
}
}
}
}
}
proc calc_phase_lags() { local i1,j1,i2,j2,k,minidx,min // 5 args - indices of mitral cells, transient time
if ($1 > nmitx || $2 > nmity || $3 > nmitx || $4 > nmity) {
print "Sorry - index out of range. Please try again."
return
}
i1 = int($1)
j1 = int($2)
i2 = int($3)
j2 = int($4)
lags.resize(0)
// for each spiketime in cell 1, find closest spike in cell 2
// Note: first and last spikes ignored since can't calculate previous ISI
if (mit[i2][j2].spiketimes.size > 0) {
for k = 1,mit[i1][j1].spiketimes.size()-2 {
if (mit[i1][j1].spiketimes.x[k] > $5) {
work = mit[i2][j2].spiketimes.c.add(-mit[i1][j1].spiketimes.x[k])
minidx = work.c.abs.min_ind()
min = work.x[minidx]
isiprev = mit[i1][j1].spiketimes.x[k-1]-mit[i1][j1].spiketimes.x[k]
isinext = mit[i1][j1].spiketimes.x[k+1]-mit[i1][j1].spiketimes.x[k]
if (min > isiprev/2 && min < isinext/2) {
if (min < 0) {
lags.append(min/isiprev)
} else {
lags.append(min/isinext)
}
}
}
}
}
}
proc calc_gran_lags() { local i1,j1,i2,j2,k,minidx,min // 5 args - indices of granule cells, transient time
if ($1 > ngranx || $2 > ngrany || $3 > ngranx || $4 > ngrany) {
print "Sorry - index out of range. Please try again."
return
}
i1 = int($1)
j1 = int($2)
i2 = int($3)
j2 = int($4)
lags.resize(0)
// for each spiketime in cell 1, find closest spike in cell 2
// Note: first and last spikes ignored since can't calculate previous ISI
if (gran[i2][j2].spiketimes.size > 0) {
for k = 1,gran[i1][j1].spiketimes.size()-2 {
if (gran[i1][j1].spiketimes.x[k] > $5) {
work = gran[i2][j2].spiketimes.c.add(-gran[i1][j1].spiketimes.x[k])
minidx = work.c.abs.min_ind()
min = work.x[minidx]
isiprev = gran[i1][j1].spiketimes.x[k]-gran[i1][j1].spiketimes.x[k-1]
isinext = gran[i1][j1].spiketimes.x[k]-gran[i1][j1].spiketimes.x[k+1]
if (min < isiprev/2 && min > isinext/2) {
lags.append(min)
}
}
}
}
}
proc time_hist() { // 1 arg - time step
work.resize(0)
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
work.append(mit[i][j].spiketimes)
}
}
hist = work.histogram(0,tstop,$1)
hist.printf("%d\n")
}
func synch_index() { local i1,j1,i2,j2,n
synchindex = 0
n = 0
for i1 = 0, nmitx-1 {
for j1 = 0, nmity-1 {
if (mit[i1][j1].spiketimes.size() > 0) {
for i2 = 0, nmitx-1 {
for j2 = 0, nmity-1 {
if (i1 != i2 || j1 != j2) {
calc_phase_lags(i1,j1,i2,j2,ttrans)
n += lags.size()
synchindex += lags.reduce("abs",0)
}
}
}
}
}
}
if (n > 0) {
return synchindex/n
} else {
return 1e6
}
}
func phaselock_index() { local n,i1,j1,i2,j2
synchindex = 0
n = 0
for i1 = 0, nmitx-1 {
for j1 = 0, nmity-1 {
if (mit[i1][j1].spiketimes.size() > 0) {
for i2 = 0, nmitx-1 {
for j2 = 0, nmity-1 {
if (i1 != i2 || j1 != j2) {
calc_phase_lags(i1,j1,i2,j2,ttrans)
if (lags.size() > 1) {
synchindex += lags.var()
n += 1
}
}
}
}
}
}
}
if (n > 0) {
synchindex = sqrt(synchindex/n)
return synchindex
} else {
return 1e6
}
}
// Procedures for writing out data --------------------------------
proc calc_smooth_hist() { // 1 arg - variance
work.resize(0)
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
work.append(mit[i][j].spiketimes)
}
}
hist = work.sumgauss(0,tstop,1,$1)
}
proc print_smooth_hist() { // 2 args - variance, filename root
calc_smooth_hist($1)
sprint(filename,"%s.smhist",$s2)
outfile.wopen(filename)
outfile.printf("# Mitral cell smoothed histogram\n")
hist.printf(outfile,"%8.3f\n")
outfile.close()
/*
work.resize(0)
hist.remove(0,ttrans)
work.spctrm(hist)
sprint(filename,"%s.pow",$s2)
outfile.wopen(filename)
outfile.printf("# Power spectrum of Mitral cell smoothed histogram\n")
work.printf(outfile,"%9.5f\n")
outfile.close()
*/
}
proc calc_gran_smooth_hist() { // 1 arg - variance
work.resize(0)
for i = 0, ngranx-1 {
for j = 0, ngrany-1 {
work.append(gran[i][j].spiketimes)
}
}
hist = work.sumgauss(0,tstop,1,$1)
}
proc print_gran_smooth_hist() { // 2 args - variance, filename root
calc_gran_smooth_hist($1)
sprint(filename,"%s.gran.smhist",$s2)
outfile.wopen(filename)
outfile.printf("# Granule cell smoothed histogram\n")
hist.printf(outfile,"%8.3f\n")
outfile.close()
//work.resize(0)
//hist.remove(0,ttrans)
//work.spctrm(hist)
//sprint(filename,"%s.gran.pow",$s2)
//outfile.wopen(filename)
//outfile.printf("# Power spectrum of Granule cell smoothed histogram\n")
//work.printf(outfile,"%9.5f\n")
//outfile.close()
}
proc print_gran_hist() { // 2 args - binsize, filename root
work.resize(0)
for i = 0, ngranx-1 {
for j = 0, ngrany-1 {
work.append(gran[i][j].spiketimes)
}
}
hist = work.histogram(0,tstop,$1)
sprint(filename,"%s.gran.hist",$s2)
outfile.wopen(filename)
outfile.printf("# Granule cell unsmoothed histogram\n")
hist.printf(outfile,"%8.3f\n")
outfile.close()
}
proc print_spiketimes() { // 3 args - indices of mitral cell plus filename root
if (numarg() == 3) {
sprint(filename,"%s_%d_%d.isi",$s3,$1,$2)
outfile.wopen(filename)
outfile.printf("# Spiketimes for mitral cell [%d][%d]",$1,$2)
mit[$1][$2].spiketimes.printf(outfile,"%10.3f")
}
if (numarg() == 1) {
sprint(filename,"%s.isi",$s1)
outfile.wopen(filename)
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
outfile.printf("[%d][%d]",i,j)
mit[i][j].spiketimes.printf(outfile,"%10.3f")
}
}
}
outfile.close()
}
proc print_raster() { // 1 arg - filename root
sprint(filename,"%s.ras",$s1)
outfile.wopen(filename)
outfile.printf("# Mitral cell raster plot\n")
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
for k = 0, mit[i][j].spiketimes.size()-1 {
outfile.printf("%d %d %d %10.3f\n",i,j,i*nmity+j,mit[i][j].spiketimes.x[k])
}
}
}
outfile.close()
}
proc print_gran_raster() { // 1 arg - filename root
sprint(filename,"%s.gran.ras",$s1)
outfile.wopen(filename)
outfile.printf("# Granule cell raster plot\n")
for i = 0, ngranx-1 {
for j = 0, ngrany-1 {
for k = 0, gran[i][j].spiketimes.size()-1 {
outfile.printf("%d %d %d %10.3f\n",i,j,i*ngrany+j,gran[i][j].spiketimes.x[k])
}
}
}
outfile.close()
}
proc print_isis() { // 3 args - indices of mitral cell plus filename root
calc_isis($1,$2,ttrans)
sprint(filename,"%s_%d_%d.isi",$s3,$1,$2)
outfile.wopen(filename)
outfile.printf("# Interspike intervals for mitral cell [%d][%d]",$1,$2)
isi.printf(outfile,"%10.3f")
outfile.close()
}
proc print_isi_stats() { // 1 arg - filename root
sprint(filename,"%s.stats",$s1)
outfile.wopen(filename)
outfile.printf("#Interspike interval statistics for mitral cells\n")
outfile.printf("# i j n mean median stdev \n")
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
calc_isis(i,j,ttrans)
outfile.printf("%3d%3d%4d",i,j,isi.size())
if (isi.size() > 0) {
outfile.printf("%8.2f%8.2f",isi.mean(),isi.median())
if (isi.size() > 1) {
outfile.printf("%8.2f\n",isi.stdev())
} else {
printf("\n")
}
} else { outfile.printf("\n") }
}
}
outfile.printf("#Interspike interval statistics for granule cells\n")
outfile.printf("# i j n mean median stdev \n")
for i = 0, ngranx-1 {
for j = 0, ngrany-1 {
calc_gran_isis(i,j,ttrans)
outfile.printf("%3d%3d%4d",i,j,isi.size())
if (isi.size() > 0) {
outfile.printf("%8.2f%8.2f",isi.mean(),isi.median())
if (isi.size() > 1) {
outfile.printf("%8.2f\n",isi.stdev())
}
} else { outfile.printf("\n") }
}
}
outfile.close()
}
proc print_lags() { local i,j // 3 args - indices of mitral cell + filename root
sprint(filename,"%s_%d_%d.lags",$s3,$1,$2)
outfile.wopen(filename)
outfile.printf("# Lag times for mitral cell [%d][%d]\n",$1,$2)
for i = 0, nmitx-1 {
for j = 0, nmity-1 {
calc_lags($1,$2,i,j,ttrans)
outfile.printf("[%d,%d]",i,j)
lags.printf(outfile,"%10.3f")
}
}
outfile.close()
}
proc print_si() { // 1 arg - fileroot
print "Calculating synchronization indices"
sprint(filename,"%s.synch",$s1)
outfile.wopen(filename)
outfile.printf("Synchronization index: %10.3f\n",synch_index())
outfile.printf("Phase-locking index: %10.3f\n",phaselock_index())
outfile.close()
}