// $Id: intfsw.hoc,v 1.75 2010/09/12 02:02:50 samn Exp $
// load_file("intfsw.hoc")
print "Loading intfsw.hoc..."
{load_file("nqs.hoc")}
{load_file("drline.hoc")}
{load_file("boxes.hoc")}
//////////////////////////////////////////////////////////////////////////////////////
// some usage
//
// adj=AdjList() //creates adjacency list used by other functions, it is global obj
// //that other functions use internally
//
// this is a variable, users can define their own, but it's not needed for hoc code:
// subs = 640/numc[SU] //# btwn 0 and 1 specifying % of cells to use in computation
// of path length and/or clustering coefficient, it can be passed into the functions
//
// this type of sequence gets excitatory path length for net:
// vd=GetNetEXL(-1,subs) // -1 means get full path lengths of ALL distances
// vd.gzmean // this will give you path length value for net
//
// this type of sequence gets excitatory cell clustering coefficient for net:
// vc=GetNetEXCC(ix[DP],ixe[SU],subs) //excitatory (DP,SU) cell clustering coefficient
// vc.gzmean // this will give you clustering coefficient value for net
//
//
//////////////////////////////////////////////////////////////////////////////////////
{declare("adj",nil,"vd",nil,"vc",nil,"allcells",0,"div","d[1][1]")}
{declare("nxadjg",nil,"vhistg","o[CTYPi+1]","vhistgd","o[CTYPi+1]","intfswb","nil")}
{declare("divnq",nil,"convnq",nil,"intfswbfl",1,"getactive",1,"loadednetworkx",0)}
{install_intfsw()}
obfunc AdjTab () { local idx,jdx localobj adj,vid
if (verbose) printf("generating adjacency matrix")
adj=new List()
for idx=0,allcells-1 adj.append(new Vector(allcells))
for idx=0,allcells-1{
if(verbose && idx%100==0)printf(".")
vid=GetDiv(idx)
for jdx=0,vid.size-1 adj.o(idx).x(vid.x(jdx))=1
}
if (verbose) printf("\n")
return adj
}
//* AdjList - get list of adjacency lists
//[optional] $1 = startid
//[optional] $2 = endid
//[optional] $3 = skip inhib cells from list
//[optional] $o4 = CE list - default uses global ce
obfunc AdjList () { local idx,jdx,startid,endid,ct,dv,skipinhib localobj adj,vid,vtmp,CE
if (verbose) printf("generating adjacency list")
if (numarg()>0) startid=$1 else startid=0
if (numarg()>1) endid=$2 else endid=allcells-1
if (numarg()>2) skipinhib=$3 else skipinhib=0
if (numarg()>3) CE=$o4 else CE=ce
adj=new List()
for idx=0,CE.count-1 adj.append(new Vector(CE.o(idx).getdvi))
CE.o(0).adjlist(adj,startid,endid,skipinhib)
return adj
}
//** adjstrg() -- get a string representation of adjacency list for use with dot
obfunc adjstrg () { local i,j localobj str,lc
lc=new List()
lc.append(new String("blue"))
lc.append(new String("red"))
str=new String2()
str.s="digraph G {"
for i=0,adj.count-1{
for j=0,adj.o(i).size-1{
sprint(str.t,"%d -> %d [color=%s];\n",i,adj.o(i).x(j),lc.o(ice(ce.o(i).type)).s)
strcat(str.s,str.t)
}
sprint(str.t,"%d [color=%s];\n",i,lc.o(ice(ce.o(i).type)).s)
strcat(str.s,str.t)
}
strcat(str.s,"}\n")
return str
}
//** net2txtf(path) -- save net to text file representation
func net2txtf () { local jdx,idx,syns localobj F,vid
F = new File()
F.wopen($s1)
if(!F.isopen){
printf("couldn't open for saving\n")
return 0
}
syns = 0
for idx=0,ce.count-1 syns += ce.o(idx).getdvi
F.printf("%d\n",ce.count)//# of cells
F.printf("%d\n",syns)//# of synapses
F.printf("%d\n",ecells)
F.printf("%d\n",icells)
for idx=0,ce.count-1{
if(ice(ce.o(idx).type)) F.printf("I ") else F.printf("E ")
F.printf("%g %g %g\n",ce.o(idx).xloc,ce.o(idx).yloc,ce.o(idx).zloc)
}
vid=new Vector(allcells)
vid.resize(0)
for idx=0,ce.count-1{
ce.o(idx).getdvi(vid)
for jdx=0,vid.size-1{
if(ice(ce.o(idx).type)) F.printf("I ") else F.printf("E ")
F.printf("%d %d\n",idx,vid.x(jdx))
}
}
F.close
return 1
}
//write net to pajek .net file , can also be used in GUESS graph visualization program
//$s1=output file path, $o2=vector of cell types to add to output file
func writepajek () { local idx,jdx,ty,ndx localobj fp,vid,vdel,lc,vty,nqc
fp=new File() vid=new Vector(allcells) vdel=new Vector(allcells)
lc=new List() lc.append(new String("Red")) lc.append(new String("Blue")) vty=$o2
fp.wopen($s1)
if(!fp.isopen())return 0
fp.printf("*Vertices %d\r\n",allcells)
for idx=0,allcells-1{
ty=ce.o(idx).type if(!vty.contains(ty))continue
fp.printf("%d \"%s%d\" ic %s\r\n",idx+1,CTYP.o(ty).s,idx,lc.o(ice(ty)).s)
}
fp.printf("*Arcslist\r\n")
for idx=0,allcells-1 {
ce.o(idx).getdvi(vid,vdel) ty=ce.o(idx).type
if(!vty.contains(ty))continue
fp.printf("%d ",idx+1)
for ndx=0,vid.size/2 {
jdx=vid.x(ndx)
if(!vty.contains(ce.o(jdx).type))continue
fp.printf("%d ",jdx+1)
}
fp.printf("1 c %s",lc.o(ice(ty)).s)
fp.printf("\r\n")
fp.printf("%d ",idx+1)
for ndx=1+vid.size/2,vid.size-1 {
jdx=vid.x(ndx)
if(!vty.contains(ce.o(jdx).type))continue
fp.printf("%d ",jdx+1)
}
// for vtr(&jdx,vid) {
// if(!vty.contains(ce.o(jdx).type))continue
// fp.printf("%d ",jdx+1)
// fp.printf("%d %d 1 c %s\r\n",idx+1,jdx+1,lc.o(ice(ty)).s)
// }
fp.printf("1 c %s",lc.o(ice(ty)).s)
fp.printf("\r\n")
}
fp.close()
return 1
}
/////////////////////////////////////////////////////////////////////////
//get path existence/distance vector ==
// vector with:
// d==0==no path between cell $1 and cell index
// and
// d>0==a path exists between cell $1 and cell index of distance d
//
// $1 = cell id to start search from
// $2 = minimum id of destination
// $3 = maximum id of destination
// $4 = max distance to search
obfunc GetPathEV () { local idx,myid,idist,startid,endid,maxdist localobj vd,vcheck,vtmp
if(adj==nil)adj=AdjList()
myid=$1
if(numarg()>1)startid=$2 else startid=0
if(numarg()>2)endid=$3 else endid=allcells-1
if(numarg()>3)maxdist=$4 else maxdist=-1
vd=new Vector(allcells)
GetPathEV_intfsw(adj,vd,myid,startid,endid,maxdist)
return vd
}
//check if network is fully connected == any cell has a path
//to any other cell
//can use speedup/efficiency improvements
func FullyConnected () { local idx localobj vd
for idx=0,allcells-1{
if(idx%100==0)printf("checking path from cell %d to others\n",idx)
vd=GetPathEV(idx)
if(vd.count(0)>1){
printf("cell %d not fully connected to other cells, only has path to %d cells\n",idx,allcells-vd.count(0))
return 0
}
}
return 1
}
//approximate path length formula
//N=# of vertices
//$1=# of 1st degree neighbors
//$2=# of 2nd degree neighbors
func ApproxL () { local z1,z2,N
N=$1 z1=$2 z2=$3
return log(N/z1)/log(z2/z1)+1
}
//get approximate path length by first getting # of
//1st & 2nd degree neighbors
func GetApproxL () { local z1,z2,i,subsamp localobj lvnn,vtmp
if(numarg()>0)subsamp=$1 else subsamp=1
if(adj==nil) if(numc[DP]) adj=AdjList(ix[DP],ixe[SU]) else adj=AdjList()
lvnn=new List()
for i=0,1{
vtmp=GetNumNeighbors(i+1,ix[DP],ixe[SU],1,adj,subsamp)
lvnn.append(vtmp)
}
{z1=lvnn.o(0).gzmean(ix[DP],ixe[SU]) printf("z1=%g\n",z1)}
{z2=lvnn.o(1).gzmean(ix[DP],ixe[SU]) printf("z2=%g\n",z2)}
return ApproxL((1-killDP)*numc[DP]+(1-killSU)*numc[SU],z1,z2)
}
//returns vector of size allcells containing avg dist from that cell
//to all other cells it is connected to
obfunc GetNetL () { local from,gzm,sid,eid localobj vdist,vtmp
if(numarg()>0)sid=$1 else sid=0
if(numarg()>1)eid=$2 else eid=allcells-1
vdist=new Vector(allcells) vtmp=new Vector(allcells)
adj=AdjList(sid,eid) //make sure initialized properly in face of prup,killp,etc.
printf("searching from id: ")
for from=sid,eid{
if(verbose && from%100==0)printf("%d...",from)
if(ce.o(from).flag("dead"))continue
vtmp=GetPathEV(from,sid,eid)
if((gzm=vtmp.gzmean)>0){
vdist.x(from)=gzm
}
}
printf("\n")
return vdist
}
// ** GetNetEXLSubPops -- get path length between excitatory subpopulations
// returns Vector of size allcells, to see path length do Vector.gzmean
// $1 == from population
// $2 == to population
// $3 == subsamp [default == 1, optional]
// $4 == take into account self-loop-length [default == 0, optional]
obfunc GetNetEXLSubPops () { local subsampi,from,selfl localobj vd,vstart,vend
from=$1 to=$2
if(numarg()>2) subsamp=$3 else subsamp=1
if(numarg()>3) selfl=$4 else selfl=0
if(adj==nil) adj=AdjList(0,allcells-1,1)//get adjacency list
{vstart=new Vector(allcells) vend=new Vector(allcells) vd=new Vector(allcells)}
for i=ix[from],ixe[from] vstart.x(i)=1
for i=ix[to],ixe[to] vend.x(i)=1
GetPathSubPop_intfsw(adj,vd,vstart,vend,subsamp,selfl)
printf("exl path from sub pop %s to %s = %g\n",CTYP.o(from).s,CTYP.o(to).s,vd.gzmean)
return vd
}
//returns vector of size allcells containing avg dist from that cell
//to all other excitatory(E) cells it is connected to
//only travels paths through E cells
//$1 == max dist , default == -1, to search all distances
//$2 == subsamp -- only use subsamp% of cells
//$3 == first turn off sub-pop to sub-pop [optional] default == -1
obfunc GetNetEXL () { local from,gzm,maxdist,subsamp localobj vdist,rdm,vuse
if(numarg()>0)maxdist=$1 else maxdist=-1
if(numarg()>1)subsamp=$2 else subsamp=1
if(adj==nil)adj=AdjList(0,allcells-1,1) //make sure initialized properly in face of prup,killp,etc.
vdist=new Vector(adj.count)
GetPathR_intfsw(adj,vdist,0,adj.count-1,-1,subsamp)
return vdist
}
//import networkx python library
func initnetworkx () {
if(loadednetworkx) return 1
if(!nrnpython("import networkx")) {
printf("initnetworkx ERRA: couldn't import networkx python library!\n")
return 0
}
loadednetworkx=1
return 1
}
//get a PythonObject containing adjacency list adj, with variable name = $s1, $2==skip I cells
obfunc NXAdjG () { local idx,jdx,skipI localobj str,py
if(!initnetworkx()) return nil
str=new String()
sprint(str.s,"%s=networkx.XDiGraph()",$s1)
py=new PythonObject()
if(!nrnpython(str.s)){
printf("NXAdjG ERRA: Couldn't evaluate %s in python!\n",str.s)
return nil
}
if(numarg()>1)skipI=$2 else skipI=1
for idx=0,allcells-1 if(!skipI || !ice(ce.o(idx).type)) {
sprint(str.s,"%s.add_node(%d)",$s1,idx)
if(!nrnpython(str.s)){
printf("NXAdjG ERRB: Couldn't add node %d to %s\n",idx,$s1)
return nil
}
}
// if(!adj)adj=AdjList(0,allcells-1,skipI)
// for idx=0,adj.count-1 for jdx=0,adj.o(idx).count-1 {
// sprint(str.s,
// }
return py
}
func tyfunc () { return ce.o($1).type }
//get between-ness centrality of all E cells, in output NQS
obfunc GetNetECent () { localobj vcent,centnq
if(adj==nil)adj=AdjList(0,allcells-1,1)
vcent=new Vector(adj.count) vcent.fill(0)
GetCentrality_intfsw(adj,vcent)
centnq=new NQS("id","type","C")
centnq.v[0].indgen(0,adj.count-1,1)
centnq.v[1].copy(centnq.v[0])
centnq.v[1].apply("tyfunc")
centnq.v[2].copy(vcent)
return centnq
}
//gets vector with loop/return path-lengths to each excitatory cell
// out.x(idx)=0 means no such path found to cell idx
obfunc GetNetELoop () { local idx localobj vdist,vloop,vf,vto
vdist=new Vector(1) vloop=new Vector(allcells) vf=new Vector(1) vto=new Vector(1)
if(adj==nil)adj=AdjList(0,allcells-1,1)//make sure initialized properly in face of prup,killp,etc.
for idx=0,allcells-1 {
if(ice(ce.o(idx).type)) {
vloop.x(idx)=0
continue
}
vf.x(0)=vto.x(0)=idx
GetPairDist_intfsw(adj,vdist,vf,vto)
vloop.x(idx)=vdist.x(0)
}
return vloop
}
// ** wirenq -- get wiring nqs, preid, postid, delay, wt1, wt2
// iff numarg()>0 $1 == only store info on excitatory connections
obfunc wirenq () { local ii,jj,exonly localobj vid,vdel,vprob,vw1,vw2,nq,vpl
if(numarg()>0) exonly=$1 else exonly=0
{vid=new Vector() vdel=new Vector() vprob=new Vector() vw1=new Vector() vw2=new Vector()}
nq=new NQS("preid","poid","del","wt1","wt2")
if(exonly){
for ii=0,allcells-1{
if(ice(ce.o(ii))) continue
ce.o(ii).getdvi(1,vid,vdel,vprob,vw1,vw2)
for jj=0,vid.size-1{
if(ice(ce.o[vid.x(jj)])) continue
nq.append(ii,vid.x(jj),vdel.x(jj),vw1.x(jj),vw2.x(jj))
}
}
} else {
for ii=0,allcells-1{
ce.o(ii).getdvi(1,vid,vdel,vprob,vw1,vw2)
for jj=0,vid.size-1{
if(ice(ce.o[vid.x(jj)])){
vw1.mul(-1)
vw2.mul(-1)
}
nq.append(ii,vid.x(jj),vdel.x(jj),vw1.x(jj),vw2.x(jj))
}
}
}
return nq
}
// ** GetNetWEXL() -- get weighted network excitatory path length
// uses directed weighted graph where distance between nodes is == delay/weight
// done for AMPA,NMDA or BOTH -- $1 == ampa flag, $2 == nmda flag
// $o3 == wirenq , [optional]
// $4 == flip order of preid, poid (convergence instead of divergence lengths) [optional]
obfunc GetNetWEXL () { local ampa,nmda,edgef,flip\
localobj vid,vdel,vprob,vw1,vw2,nq,vpl,vs,vpre,vpo
if(numarg()>0) ampa=$1 else ampa=1
if(numarg()>1) nmda=$2 else nmda=1
if(numarg()>2) nq=$o3 else nq = wirenq(1)
if(numarg()>3) flip=$4 else flip=0
vpl=new Vector(allcells)
vdel=new Vector()
if(flip){ // flip pre and po
vpre=nq.getcol("poid")
vpo=nq.getcol("preid")
} else {
vpre=nq.getcol("preid")
vpo=nq.getcol("poid")
}
nq.getcol("del",vdel)
if(ampa && nmda){
vs=new Vector()
vs.copy(nq.getcol("wt1"))
vs.add(nq.getcol("wt2"))
GetWPath_intfsw(vpre,vpo,vs,vdel,vpl)
} else if(ampa){
GetWPath_intfsw(vpre,vpo,nq.getcol("wt1"),vdel,vpl)
} else if(nmda){
GetWPath_intfsw(vpre,vpo,nq.getcol("wt2"),vdel,vpl)
} else {
if(numarg()<=2)nqsdel(nq)
return nil
}
if(numarg()<=2)nqsdel(nq)
return vpl
}
// ** GetNetWL() -- get weighted network path length, takes inhibitory contributions as
// weight/delay , and excitatory contributions as delay/weight
// only uses AMPA/GABAA or NMDA/GABAB
obfunc GetNetWL () { local ampagabaa localobj vid,vdel,vprob,vw1,vw2,nq,vpl
if(numarg()>0) ampagabaa=$1 else ampagabaa=1
nq = wirenq(0)
vpl=new Vector(nq.size)
if(ampagabaa){
GetWPath_intfsw(nq.getcol("preid"),nq.getcol("poid"),nq.getcol("wt1"),nq.getcol("del"),vpl)
} else {
GetWPath_intfsw(nq.getcol("preid"),nq.getcol("poid"),nq.getcol("wt2"),nq.getcol("del"),vpl)
}
return vpl
}
// ** GetNetEXCCSubPops -- get clustering coefficient between excitatory subpopulations
// returns Vector of size allcells, to see path length do Vector.gzmean
// $1 == from population
// $2 == to population
// $3 == subsamp [default == 1, optional]
obfunc GetNetEXCCSubPops () { local subsampi,from localobj vd,vstart,vend
from=$1 to=$2
if(numarg()>2) subsamp=$3 else subsamp=1
if(adj==nil) adj=AdjList(0,allcells-1,1)//get adjacency list
{vstart=new Vector(allcells) vend=new Vector(allcells) vd=new Vector(allcells)}
for i=ix[from],ixe[from] vstart.x(i)=1
for i=ix[to],ixe[to] vend.x(i)=1
GetCCSubPop_intfsw(adj,vd,vstart,vend,subsamp)
printf("excc from sub pop %s to %s = %g\n",CTYP.o(from).s,CTYP.o(to).s,vd.nnmean)
return vd
}
//get clustering coefficient vector for excitatory cells
//usage: vcc = GetNetEXCC()
//vcc.x(i) is clustering coefficient of cell i (must be >= 0.0 && <= 1.0)
//otherwise there was a problem...
//vcc.mean(ix[DP],ixe[SU]) is clustering coefficient of excitatory cells for entire network
obfunc GetNetEXCC () { local idx,sid,eid,subsamp localobj vcc,vuse
if(adj==nil)adj=AdjList(0,allcells-1,1)
if(numarg()>0)sid=$1 else sid=0
if(numarg()>1)eid=$2 else eid=adj.count-1
if(numarg()>2)subsamp=$3 else subsamp=1
vcc=new Vector(adj.count)
GetCCR_intfsw(adj,vcc,sid,eid,subsamp)
return vcc
}
//returns vector of size allcells containing num of neighbors <= $1 distance away
//for each cell
obfunc GetNumNeighbors () { local maxdist,startid,endid,exact,subsamp,sead localobj vdist,vtmp,vuse,rdm
maxdist=$1
if(numarg()>1)startid=$2 else startid=ix[DP]
if(numarg()>2)endid=$3 else endid=ixe[SU]
if(numarg()>3)exact=$4 else exact=0
if(numarg()>4)adj=$o5 else if(adj==nil) adj=AdjList()//make sure initialized properly in face of prup,killp,etc.
if(numarg()>5)subsamp=$6 else subsamp=1
vdist=new Vector(allcells) vtmp=new Vector(allcells)
printf("searching from id: ")
CountNeighborsR_intfsw(adj,vdist,startid,endid,maxdist,subsamp)
return vdist
}
//returns vector of size allcells containing # of recurrent connections terminating on cell
//i in out.x(i)
//$1 == from type, -1 means from all E cells, -2 means all I cells, as a vec from all types in vec
//$2 == thru type, -1 means thru all E cells, -2 means all I cells, as a vec thru all types in vec
obfunc GetRecurVec () { local from,thru,ct localobj vRC,vfrom,vthru,vtmp
vRC=new Vector(allcells) vfrom=new Vector(allcells) vthru=new Vector(allcells)
vRC.fill(0)
if(adj==nil)adj=AdjList()
if(numarg()>0) {
if(argtype(1)==0) {
if($1>=0) {
vfrom.fill(1,ix[$1],ixe[$1]) //from only a specific type
} else if($1==-1) { // E cells
for ctt(&ct) if(!ice(ct)) vfrom.fill(1,ix[ct],ixe[ct])
} else for ctt(&ct) if(ice(ct)) vfrom.fill(1,ix[ct],ixe[ct]) // I cells
} else {
for vtr(&from,$o1) vfrom.fill(1,ix[from],ixe[from]) //from a bunch of types
}
} else vfrom.fill(1)
if(numarg()>1) {
if(argtype(1)==0) {
if($1>=0) {
vthru.fill(1,ix[$2],ixe[$2])
} else if($1==-1) { // E cells
for ctt(&ct) if(!ice(ct)) vthru.fill(1,ix[ct],ixe[ct])
} else for ctt(&ct) if(ice(ct)) vthru.fill(1,ix[ct],ixe[ct]) // I cells
} else {
for vtr(&thru,$o1) vthru.fill(1,ix[thru],ixe[thru]) //thru a bunch of types
}
} else vthru.fill(1)
GetRecurCount_intfsw(adj,vRC,vfrom,vthru)
return vRC
}
//* DivNQS([cell list]) - gets NQS with # of outputs of a given type from each cell
obfunc DivNQS () { local a,idx,x,flag localobj nq,vc,vd,vo,vty,st,CE,vcnt,xo
if(numarg()>0)CE=$o1 else CE=ce
st=new String2()
nq=new NQS("id","type")
a=allocvecs(vc,vd,vty,vo,vcnt,CTYPi+1)
vrsz(0,vc,vd,vo,vty) vcnt.resize(CTYPi)
for ltr(xo,CE) vcnt.x(xo.type)+=1
for x=0,CTYPi-1 if(vcnt.x(x)) {
{sprint(st.s,"to%s",CTYP.o(x).s) nq.resize(st.s) vty.append(x)} // vty -- type vec
}
nq.clear(CE.count) // make big enough
flag=getactive+0.2
for idx=0,CE.count-1 {
CE.o(idx).getdvi(flag,vc) // picks up for all existing (CTYP) cell types
vo.index(vc,vty) // only take the ones for the relevant types
revec(vd,idx,CE.o(idx).type) vd.append(vo) // put in the id and type values for the postcell
nq.append(vd)
}
dealloc(a)
return nq
}
//* ConvNQS([cell list]) - gets NQS with # of inputs of a given type onto each cell
obfunc ConvNQS () { local a,idx,x,flag localobj nq,vc,vd,vo,vty,st,CE,vcnt,xo
if(numarg()>0)CE=$o1 else CE=ce
st=new String2()
nq=new NQS("id","type")
a=allocvecs(vc,vd,vty,vo,vcnt,CTYPi+1)
vrsz(0,vc,vd,vty) vcnt.resize(CTYPi)
for ltr(xo,CE) vcnt.x(xo.type)+=1
for x=0,CTYPi-1 if(vcnt.x(x)) {
{sprint(st.s,"f%s",CTYP.o(x).s) nq.resize(st.s) vty.append(x)} // vty -- type vec
}
nq.clear(CE.count) // make big enough
flag=getactive+0.2
for idx=0,CE.count-1 {
CE.o(idx).getconv(flag,vc) // picks up for all possible cell types
vo.index(vc,vty) // only take the ones for the relevant types
revec(vd,idx,CE.o(idx).type) vd.append(vo) // put in the id and type values for the postcell
nq.append(vd)
}
dealloc(a)
return nq
}
//display conv hists in graphs
proc ShowConvHists () { local from,to,jj,ii,num localobj vt,vt2,mystr,o,xo,yo
mystr=new String() hflg=2 ers=0
if(numarg()<1 && convnq!=nil)nqsdel(convnq)
if(convnq==nil) convnq=ConvNQS()
convnq.verbose=0
num=0
for ctt(&to) num+=1 // count the active cells
if (intfswbfl) {
for ltr(yo,boxerl) if (strm(yo.name,"CONV")) o=yo
if (o!=nil) { // reuse this box
if (o.size!=num) {printf("ERR: wrong # of graphs in tray: %d %d\n",o.size,num) return}
for ltr(xo,o.gl) xo.erase_all
} else o=mktray("CONV",num)
for ctt(&to,&ii) vhistg[to]=o.gl.o(ii)
} else for ctt(&to) {
if(vhistg[to]==nil || numarg()<1) vhistg[to]=new Graph() else vhistg[to].erase_all
}
for ctt(&to) {
sprint(mystr.s,"conv hist onto %s",CTYP.o(to).s)
vhistg[to].color(to)
vhistg[to].label(0.35,0.95,mystr.s)
for ctt(&from,&ii){
if(!div[from][to]) continue
clr=from
if(convnq.select("type",to)){
sprint(mystr.s,"f%s",CTYP.o(from).s)
vt=convnq.getcol(mystr.s)
sprint(mystr.s,"from %s avg=%g",CTYP.o(from).s,vt.mean)
if (vt.min==vt.max) {
vhistg[to].mark(vt.min,0,"S",10,clr,4)
} else {
hist(vhistg[to],vt)
}
vhistg[to].color(clr)
vhistg[to].label(0.5,0.88-0.05*ii,mystr.s)
}
}
vhistg[to].exec_menu("View = plot")
}
convnq.verbose=1
}
//display div hists in graphs -- skips inhibitory cells for now...
proc ShowDivHists () { local from,to,ii,jj,num,rows,cols localobj vt,mystr,o,xo,yo
mystr=new String() hflg=2 ers=0
if(numarg()<1 && divnq!=nil)nqsdel(divnq)
if(divnq==nil) divnq=DivNQS()
divnq.verbose=0
num=0
for ctt(&from) num+=1 // count the active cells
if (intfswbfl) {
for ltr(yo,boxerl) if (strm(yo.name,"DIV")) o=yo
if (o!=nil) { // reuse this box
if (o.size!=num) {printf("ERR: wrong # of graphs in tray: %d %d\n",o.size,num) return}
for ltr(xo,o.gl) xo.erase_all
} else o=mktray("DIV",num)
for ctt(&from,&ii) vhistgd[from]=o.gl.o(ii)
} else for ctt(&from) {
if(vhistgd[from]==nil || numarg()<1) vhistgd[from]=new Graph() else vhistgd[from].erase_all
}
for ctt(&from,&jj) {
sprint(mystr.s,"div hist from %s",CTYP.o(from).s)
vhistgd[from].color(from)
vhistgd[from].label(0.35,0.95,mystr.s)
for ctt(&to,&ii){
if(!div[from][to]) continue
clr=to
if(divnq.select("type",from)){
sprint(mystr.s,"to%s",CTYP.o(to).s)
vt=divnq.getcol(mystr.s)
sprint(mystr.s,"to %s avg=%g",CTYP.o(to).s,vt.mean)
if(vt.min==vt.max){
vhistgd[from].mark(vt.min,0,"S",10,clr,4)
} else {
hist(vhistgd[from],vt)
}
vhistgd[from].color(clr)
vhistgd[from].label(0.5,0.88-0.05*ii,mystr.s)
}
}
vhistgd[from].exec_menu("View = plot")
}
divnq.verbose=1
}
//get index of GetCellNQ arg which column is needed, $s1=colname
func getcellnqcolid () { localobj str
str=new String()
str.s=$s1
if(!strcmp($s1,"wexl")){
return 1
} else if(!strcmp($s1,"snq")) {
return 2
} else if(!strcmp($s1,"fnq")) {
return 3
} else if(!strcmp($s1,"C")) {
return 4
} else if(!strcmp($s1,"exl")) {
return 5
} else if(!strcmp($s1,"excc")) {
return 6
} else if(!strcmp($s1,"conv") || strm($s1,"f")) {
return 7
} else if(!strcmp($s1,"div") || strm($s1,"to")) {
return 8
} else if(!strcmp($s1,"blk")) {
return 9
}
return 0
}
func ifunc () { return ice(ce.o($1).type) }
//get nqs with cell properties including: centrality, exl, excc, div to all types, conv to all types
//$1=do wexl,$2=do snq,$3=do fnq,$4=do C,$5=do exl,$6=do excc,$7=do convnq,$8=do div,$9=do block
obfunc GetCellNQ () { local i,id,n,doexl,doexcc,doconv,doC,dodiv,doblk\
localobj nq,nqt,vv,snq,fnq
nq=new NQS("id","type") adj=nil
nq.v[0].indgen(0,allcells-1,1) nq.v[1].copy(nq.v[0]) nq.v[1].apply("tyfunc")
if(numarg()>3)doC=$4 else doC=1
if(numarg()>4)doexl=$5 else doexl=1
if(numarg()>5)doexcc=$6 else doexcc=1
if(numarg()>6)doconv=$7 else doconv=1
if(numarg()>7)dodiv=$8 else dodiv=1
if(numarg()>8)doblk=$9 else doblk=1
if(doC){
if (verbose) printf("getting centrality nq\n") nqt=GetNetECent()
nq.resize("C") nq.v[nq.m-1].copy(nqt.v[nqt.m-1]) nqsdel(nqt)
}
if(numarg()>0) if($1) {
{if (verbose) printf("getting wexl\n")
vv=GetNetWEXL() nq.resize("wexl") nq.v[nq.m-1].copy(vv)}
}
if(doexl){
{if (verbose) printf("getting exl\n")
vv=GetNetEXL() nq.resize("exl") nq.v[nq.m-1].copy(vv)}
}
if(doexcc){
{if (verbose) printf("getting excc\n")
vv=GetNetEXCC() nq.resize("excc") nq.v[nq.m-1].copy(vv)}
}
if(doconv){
if (verbose) printf("getting convnq\n") nqt=ConvNQS()
for i=2,nqt.m-1 {
nq.resize(nqt.s[i].s) nq.v[nq.m-1].copy(nqt.v[i])
}
nqsdel(nqt)
}
if(dodiv){
if (verbose) printf("getting divnq\n") nqt=DivNQS()
for i=2,nqt.m-1 {
nq.resize(nqt.s[i].s) nq.v[nq.m-1].copy(nqt.v[i])
}
nqsdel(nqt)
}
{nq.resize("inhib") nq.pad() nq.v[nq.m-1].copy(nq.v[0]) nq.v[nq.m-1].apply("ifunc")}
if(numarg()>1) if($2) {
if (verbose) printf("getting spike counts\n")
vv=printlist.o(0).vec nq.resize("spikes") nq.pad() nq.v[nq.m-1].fill(0)
for vtr(&i,vv) nq.v[nq.m-1].x(i)+=1
}
if(doblk){
nq.resize("block") nq.pad() for i=1,allcells-1 nq.v[nq.m-1].x(i)=ce.o(i).spkcnt(i,i,2)
}
if(numarg()>2) if($3 && name_declared("FreqNQS")) {
if (verbose) printf("getting FreqNQS\n")
snq=SpikeNQS(printlist.o(0))
fnq=FreqNQS(snq,20,0,0)
for i=0,allcells-1 if((n=fnq.select("ID",i))) {
if(n>0){
nq.v[nq.m-1].x(i)=fnq.getcol("Freq").mean
} else {
nq.v[nq.m-1].x(i)=fnq.getcol("Freq").x(0)
}
}
}
if(snq!=nil)nqsdel(snq)
if(fnq!=nil)nqsdel(fnq)
return nq
}
//get nqs with rand value for each cell, $1==seed
obfunc GetRandCellNQ () { local i localobj nq,rd
nq=new NQS("id","type","rand")
rd=new Random()
rd.ACG($1)
for i=0,allcells-1 nq.append(i,ce.o(i).type,rd.normal(0,1))
return nq
}
// from ShowDivHists()
proc prdiv () { local from,to,jj,ii,num,rows,cols localobj vt,mystr,o,xo,yo
if (numarg()==1) o=$o1 else o=divnq
if (o==nil) o=divnq=DivNQS()
o.verbose=0
for ctt(&from,&jj) { printf("\ndiv from %s: ",CTYP.o(from).s)
if (o.select("type",from)) for ctt(&to,&ii) {
vt=o.getcol(CTYP.o(to).s)
printf(" to %s avg=%02.3f +- %02.3f",CTYP.o(to).s,vt.mean,vt.stdev)
}}
print ""
o.verbose=1
}
proc prconv () { local from,to,jj,ii,num,rows,cols localobj vt,mystr,o,xo,yo
if (numarg()==1) o=$o1 else o=convnq
if (o==nil) o=convnq=ConvNQS()
o.verbose=0
for ctt(&to,&jj) { printf("\nconv to %s: ",CTYP.o(to).s)
if (o.select("type",to)) for ctt(&from,&ii) {
vt=o.getcol(CTYP.o(from).s)
printf(" from %s avg=%02.3f +- %02.3f",CTYP.o(from).s,vt.mean,vt.stdev)
}}
print ""
o.verbose=1
}