begintemplate SpikePlot2
public sources, vecs, g, update
public map, save_data, save, b
public flush, begin, plot, size, view_count, fastflush, simgraph
external addplot, tstop
objref sources, vecs[1], nc, g, this, y,ps, tobj, b, outlist, nil
strdef tstr, modestr, windowTitle
proc init() {
	CELL 		=0
	ARTIFICIAL 	=1
	SECTION 	=2
	SECTIONLIST	=3
	NETWORKSOURCE=4
	NETWORKARTIFICIALSOURCE=5
	outlist = new List()
	fwindow = 100
	binwidth = 1
	modestr = "Spikes   "
	mode=1
	
	spikeplotstyle=0
	marksize=4
	markcolor=1
	useline=0
		
	y = new Vector(1000)
	ps=new Vector(1000)
	sources = $o1
	sourcetype=$2
	
	subset_start=-1
	subset_end=-1
	lsubset_start=0
	lsubset_end=0

    n=0
    
    if(numarg()>2){
    	sprint(windowTitle,"%s",$s3)
    }else{
		sprint(windowTitle, "%s for %s", this, sources)
	}
    
    
    // Threshold can only be set once for a single target cell
	// and we don't want to have the spikeplot to interfere with network parameters.

    
    if (numarg() == 2 || numarg() == 3 ) {
		build()
		map()
		size(0,tstop,0,0)
	}
}
proc map() {
	//sprint(tstr, "%s for %s", this, sources)
	if (numarg() > 1) {
		b.map(windowTitle, $2,$3,$4,$5)
	}else{
		b.map(windowTitle)
	}
	update()
	flush()
}
proc unmap() {
	b.unmap()
	g = nil
}
proc build() {
	b = new VBox(3)
	b.priority(600)
	b.save("save()")
	b.ref(this)
	b.dismiss_action("unmap()")
	b.intercept(1)
	xpanel("")
	xmenu("Plot")
	xbutton("Update", "update() flush()")
	xmenu("Plot Style")
		xradiobutton("Spikes", "pmode(1)", mode==1)
		xradiobutton("Frequency (Gaussian Window)", "pmode(2)", mode==2)
		xradiobutton("ISI Histogram (Gaussian Window)", "pmode(3)", mode==3)
		xradiobutton("ISI Histogram (Binned)", "pmode(4)", mode==4)
		xradiobutton("Cumulative Frequency (Gaussian Window)", "pmode(5)", mode==5)
		xradiobutton("Cumulative Frequency (Binned)", "pmode(6)", mode==6)
		xradiobutton("Cumulative ISI Histogram (Gaussian Window)", "pmode(7)", mode==7)
		xradiobutton("Cumulative ISI Histogram (Binned)", "pmode(8)", mode==8)
		xradiobutton("Powerspectrum (Gaussian Window)", "pmode(9)", mode==9)
	xmenu()	
	xmenu("Spike Plot Style")
		xradiobutton("Pipe", "pspikeplotstyle(0)", spikeplotstyle==0)
		xradiobutton("Filled Circle", "pspikeplotstyle(1)", spikeplotstyle==1)
		xradiobutton("Filled Triangle", "pspikeplotstyle(2)", spikeplotstyle==2)
		xradiobutton("Filled Square", "pspikeplotstyle(3)", spikeplotstyle==3)
		xradiobutton("Open Circle", "pspikeplotstyle(4)", spikeplotstyle==4)
		xradiobutton("Open Triangle", "pspikeplotstyle(5)", spikeplotstyle==5)
		xradiobutton("Open Square", "pspikeplotstyle(6)", spikeplotstyle==6)
		xbutton("Pick Size and Color","EditMark()")
		xstatebutton("Use Line",&useline ,"flush()")
	xmenu()
	
	xbutton("Select Subset","selectSubset()")

	xmenu()
	xvarlabel(modestr)
	xpvalue("Gaussian Width (ms)", &fwindow, 1, "flush()")
	xpvalue("Bin Width (ms)     ", &binwidth, 1, "flush()")

	xpanel()
	g = new Graph()
	b.intercept(0)
	addplot(this, 1)
	begin()
	pmode(mode)
}
proc pmode() {
	mode = $1
	if (mode == 1) {
		modestr = "Spikes   "
	}else if (mode == 2) {
		modestr = "Frequency (Gaussian Window)"
	}else if (mode == 3) {
		modestr = "ISI Histogram (Gaussian Window)"
	}else if (mode == 4) {
		modestr = "ISI Histogram (Binned)"
	}else if (mode == 5) {
		modestr = "Cumulative Frequency (Gaussian Window)"
	}else if (mode == 6) {
		modestr = "Cumulative Frequency (Binned)"
	}if (mode == 7) {
		modestr = "Cumulative ISI Histogram (Gaussian Window)"
	}else if (mode == 8) {
		modestr = "Cumulative ISI Histogram (Binned)"
	}else if (mode == 9) {
		modestr = "Powerspectrum (Gaussian Window)"
	}
	
  flush()
}

proc pspikeplotstyle(){
	spikeplotstyle=$1
	flush()
}

proc EditMark(){
	xpanel("Edit Mark Size and Color")
		xpvalue("Mark size",  &marksize  , 0, "flush()")
		xpvalue("Mark color", &markcolor , 0, "flush()")
	xpanel()
}

proc selectSubset(){
	lsubset_start=subset_start
	lsubset_end=subset_end
	
	xpanel("Select Subset")
		xpvalue("Subset Start",  &lsubset_start , 0, "setSubset()")
		xpvalue("Subset End", &lsubset_end , 0, "setSubset()")
	xpanel()
	
	
}

proc setSubset(){
	//print "setSubset start: ",  lsubset_start, " end: ", lsubset_end , " n: ", n
	if(0 <= lsubset_start && lsubset_start <= lsubset_end && lsubset_end <= n){
		subset_start=lsubset_start
		subset_end=lsubset_end
		flush()
	}
	lsubset_start=subset_start
	lsubset_end=subset_end
}


proc update() {local i localobj vec
	
	if(sourcetype==ARTIFICIAL || sourcetype==CELL || sourcetype==SECTION || sourcetype==NETWORKSOURCE || sourcetype==NETWORKARTIFICIALSOURCE){
		n = sources.count
	}else if (sourcetype==SECTIONLIST){
		n=0
		forsec sources {
			n=n+1
		}
	}
    
    if(n<subset_end || subset_end==-1) {
		subset_end=n
	}
	
	if(n<subset_start|| subset_start==-1) {
		subset_start=0
	}
    
	if (n == 0) return
	
	objref vecs[n]
	for (i=outlist.count-1; i >= 0; i -= 1) {
		if (outlist.object(i).valid == 0) {
			outlist.remove(i)
		}
	}
	
	if(sourcetype==ARTIFICIAL || sourcetype==CELL || sourcetype==SECTION || sourcetype==NETWORKSOURCE || sourcetype==NETWORKARTIFICIALSOURCE){
		for i=0, n-1 {
			vecs[i] = new Vector(0)
			tobj = sources.object(i)
			
			if(sourcetype==ARTIFICIAL){
				nc = new NetCon(tobj, nil)
			}
			
			if(sourcetype==CELL){
				tobj.soma  nc = new NetCon(&v(1), nil)	
			}
			
			if(sourcetype==SECTION){
				tobj.sec  nc = new NetCon(&v(1), nil)	
			}
			
			if(sourcetype==NETWORKSOURCE){
				tobj.sec().sec  nc = new NetCon(&v(1), nil)	
			}
			
			if(sourcetype==NETWORKARTIFICIALSOURCE){
				 nc = new NetCon(tobj.artificial_cell(), nil)	
			}
			//tobj.connect2target(nil, nc)
			
			if (nc.precelllist.count < 2) {
					outlist.append(nc)
			}
			
// 			vec=nc.get_recordvec()
// 			if(vec==nil){
				nc.record(vecs[i])
// 			}else{
// 				vecs[i]=vec
// 			}
			
			vecs[i].label(tstr)
						
			// nc.threshold=threshold threshold can only be set once for a single target cell
			// and we don't want to have the spikeplot to interfere with network parameters.
			
			nc.delay=0
		}
	}
	
	if(sourcetype==SECTIONLIST ){
		i=0
		forsec sources {

			vecs[i] = new Vector(0)
			
			if(sourcetype==SECTIONLIST){
				 nc = new NetCon(&v(1), nil)	
			}
			//tobj.connect2target(nil, nc)
			
			if (nc.precelllist.count < 2) {
					outlist.append(nc)
			}
			
// 			vec=nc.get_recordvec()
// 			if(vec==nil){
				nc.record(vecs[i])
// 			}else{
// 				vecs[i]=vec
// 			}

			vecs[i].label(tstr)
			// nc.threshold=threshold threshold can only be set once for a single target cell
			// and we don't want to have the spikeplot to interfere with network parameters.
			nc.delay=0
			i=i+1
		}
	}
	objref nc, tobj
}

proc simgraph() {}
proc begin() {}

func view_count() {
	if (g == nil) {
		return 0
	}
	return g.view_count()
}
proc plot() {}
func size() {
	if (numarg() == 4) {
		g.size($1,$2,0,subset_end+1-subset_start)
		return 1.
	}else{
		return g.size($1)
	}
}
proc fastflush() {}

proc flush() {local i
	g.erase_all
	g.vfixed(1)
	g.label(.9,1)
	if (mode == 1) {			//"Spikes   "
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y.resize(vecs[i].size).fill(i+1-subset_start)
			y.label(vecs[i].label)
			if (spikeplotstyle==0){
				y.mark(g, vecs[i], "|", marksize, markcolor, 1)  //	Pipe"
			}else if (spikeplotstyle==1){
				y.mark(g, vecs[i], "O", marksize, markcolor, 1)  //	"Filled Circle"
			}else if (spikeplotstyle==2){
				y.mark(g, vecs[i], "T", marksize, markcolor, 1)	 // "Filled Triangle"
			}else if (spikeplotstyle==3){
				y.mark(g, vecs[i], "S", marksize, markcolor, 1)	 // "Filled Square" 
			}else if (spikeplotstyle==4){
				y.mark(g, vecs[i], "o", marksize, markcolor, 1)  //	"Open Circle"
			}else if (spikeplotstyle==5){
				y.mark(g, vecs[i], "t", marksize, markcolor, 1)	 // "Open Triangle"
			}else if (spikeplotstyle==6){
				y.mark(g, vecs[i], "s", marksize, markcolor, 1)	 // "Open Square" 
			}
			if(1==useline){	
				y.line(g, vecs[i], markcolor, 0)
			}
		}
		size(0,tstop,0,0)
	}else if (mode == 2) { //"Frequency (Gaussian Window)"
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y = vecs[i].sumgauss(0, tstop, binwidth, fwindow)
			y.label(vecs[i].label)
			y.mul(1000).line(g, y.c.indgen(0, binwidth), 1,1)
			g.exec_menu("View = plot")
		}
	}else if (mode == 3) {//"ISI Histogram (Gaussian Window)"
		for (i=subset_end-1; i >= subset_start; i -= 1) if (vecs[i].size > 1){
			y = vecs[i].c.deriv(1,1)
			high = y.max
			y = y.sumgauss(0, high, binwidth, fwindow)
			y.label(vecs[i].label)
			y.line(g, y.c.indgen(0, binwidth), 1,1)
			g.exec_menu("View = plot")
		}
	}else if (mode == 4) {//"ISI Histogram (Binned)"
		for (i=subset_end-1; i >= subset_start; i -= 1) if (vecs[i].size > 1){
			y = vecs[i].c.deriv(1,1)
			high = y.max
			y = y.histogram(0, high, binwidth)
			y=y.c(1)
			y.label(vecs[i].label)
			y.line(g, y.c.indgen(0, high/50), 1,1)
			g.exec_menu("View = plot")
		}
	}else if (mode == 5) {//"Cumulative Frequency (Gaussian Window)"
		y  = new Vector ()
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y = y.append(vecs[i])
		}
		y = y.sumgauss(0, tstop, binwidth, fwindow)
		y.label(modestr)
		y.mul(1000).line(g, y.c.indgen(0, binwidth), 1,1)
		g.exec_menu("View = plot")
	}else if (mode == 6) {//"Cumulative Frequency (Binned)"

		y  = new Vector ()
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y = y.append(vecs[i])
		}
		high = y.max
		y = y.histogram(0, tstop, binwidth)
		y=y.c(1)
		y.label(modestr)
		y.line(g, y.c.indgen(0, binwidth), 1,1)
		g.exec_menu("View = plot")
	}else if (mode == 7) {//"Cumulative ISI Histogram (Gaussian Window)"
		y  = new Vector ()
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y = y.append(vecs[i])
		}
		if (y.size > 1){
			y = y.c.deriv(1,1)
			high = y.max
			y = y.sumgauss(0, high, binwidth, fwindow)
			y.label(modestr)
			y.line(g, y.c.indgen(0, binwidth), 1,1)
			g.exec_menu("View = plot")
		}
	}else if (mode == 8) {//"Cumulative ISI Histogram (Binned)"
		y  = new Vector ()
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y = y.append(vecs[i])
		}
		if (y.size > 1){
			y = y.c.deriv(1,1)
			high = y.max
			y = y.histogram(0, high, binwidth)
			y=y.c(1)
			y.label(modestr)
			y.line(g, y.c.indgen(0, binwidth), 1,1)
			g.exec_menu("View = plot")
		}	
	}else if (mode == 9) {//"Powerspectrum"
		y  = new Vector ()
		ps =new Vector()
		for (i=subset_end-1; i >= subset_start; i -= 1) {
			y = y.append(vecs[i])
		}
		if (y.size > 1){
		  y = y.sumgauss(0, tstop,binwidth, fwindow)
			ps.spctrm(y)		// spectrum
			ps.label(modestr)
			ps.line(g, ps.c.indgen(0, 1000/(2*binwidth),1000/(2*binwidth*ps.size())), 1,1)
			g.exec_menu("View = plot")
		}	
	}
	g.flush()
}


proc save() {
	b.save("load_file(\"netbild.hoc\")\n}")
	save_data(b, "ocbox_")
	b.save("{")
	
}

proc save_data() {
	sprint(tstr, "{%s = new SpikePlot2(%s,1)}", $s2, net) $o1.save(tstr)
	sprint(tstr, "{object_push(%s)}", $s2) $o1.save(tstr)
	sprint(tstr, "mode = %g", mode) $o1.save(tstr)	
	sprint(tstr, "spikeplotstyle= %g", spikeplotstyle) $o1.save(tstr)
	sprint(tstr, "marksize= %g",  marksize ) $o1.save(tstr)
	sprint(tstr, "markcolor= %g", markcolor) $o1.save(tstr)
	sprint(tstr, "useline= %g",  useline) $o1.save(tstr)
	sprint(tstr, "fwindow = %g", fwindow) $o1.save(tstr)
	sprint(tstr, "binwidth = %g", binwidth) $o1.save(tstr)
	$o1.save("build()")
	sprint(tstr, "subset_start=%g",subset_start) $o1.save(tstr)
	sprint(tstr, "subset_end = %g",subset_end) $o1.save(tstr)
	sprint(tstr, "{g.size(%g,%g,%g,%g)}", \
	g.size(1), g.size(2), g.size(3), g.size(4))
	$o1.save(tstr)
	$o1.save("{object_pop()}")

}

endtemplate SpikePlot2