load_file("../templates/Pyram_WT_modif.tem")
load_file("../templates/FS_WT_modif.tem")

begintemplate string //Equivalent to ronalds string handler
public str
strdef str
proc init(){
    str=$s1
}
endtemplate string

objref word,word1, word3,word4,rand_gen,cells,nil,stim_list
rand_gen=new Random(34)//seeds 34,78569783335
strdef end
word=new string("")
word1=new string("")
use_mcell_ran4(1)
strdef num_flag
n_types=2  //number of cell types  indx1==0 =>pyramidal indx1==1 =>fast spiking
//sgr subgrps of spikes to a giiven population
//NL=> number of pyramidal/fast spiking layers
    for(Cell_type=0;Cell_type<n_types;Cell_type+=1){
        if(Cell_type==0){NL=n_layerP end="P" sgr=sub_spkE}else{if(Cell_type==1){NL=n_layerFS end="FS" sgr=sub_spkI}}
          for(idx_spk=0;idx_spk<=sgr;idx_spk+=1){
            sprint(word.str, "objref Spikesource%s%g[%g],excit_syn%s%g[%g],Ic%s[%g]",end,idx_spk,NL,end,idx_spk,NL,end,NL)    
            execute(word.str)  
            //print word.str
             for Ly=0,NL-1{    
             sprint(word1.str,"Spikesource%s%g[%g]=new List() excit_syn%s%g[%g]=new List() Ic%s[%g]=new List()",end,idx_spk,Ly,end,idx_spk,Ly,end,Ly)
             execute(word1.str)
             
            } 
          }                 
        }
    
      
    obfunc createSpikeGen(){local ctr,i,ii,interv,numb,start,noise,inf,inf1,max, max1,cell_type,layer localobj target_cells
    strdef end1   
    target_cells=$o1 interv=$2 numb=$3/*<= not in use*/ start=$4 noise=$5 excit_v=$6 excit_tau=$7 
    inf=$8 max=$9 cell_type=$10 layer=$11 syn_cond=$12 sub_idx=$13
    word3=new string("")
    if(target_cells.count()>0){                                                                         
    for i=0,target_cells.count()-1 target_cells.o(i).soma{
    inf1=target_cells.o(i).Area()*inf // arbitrary scale factor 
    max1=target_cells.o(i).Area()*max // arbitrary scale factor 
    if(cell_type==0){end1="P"}else{if(cell_type==1){end1="FS"}}     
          for(ctr=0;ctr<=sub_idx;ctr+=1){
            if(ctr==1){interv=$14 noise=1 syn_cond=$15 //attention!!! this incorporates "RANDOM" additional spike-trains to the measumerents
              //print "additional syn in cell_type"," ",cell_type," interval, noise and syn_weight ", interv," ",noise," ",syn_cond
            }          
          sprint(word3.str,"Spikesource%s%g[%g].append(new NetStim(0.5))",end1,ctr,layer)
          execute(word3.str)    
        //sprint(word3.str,"Spikesource%s%g[%g].o(%g).interval=int(tstop/(%g))",end1,ctr,layer,i,numb)
          sprint(word3.str,"Spikesource%s%g[%g].o(%g).interval=%g",end1,ctr,layer,i,interv)    
          execute(word3.str)
      
          sprint(word3.str,"Spikesource%s%g[%g].o(%g).number=int(tstop/(%g))",end1,ctr,layer,i,interv)
          //sprint(word3.str,"Spikesource%s%g[%g].o(%g).number=%g",end1,ctr,layer,i,numb)    
          execute(word3.str)
    
          sprint(word3.str,"Spikesource%s%g[%g].o(%g).start=%g",end1,ctr,layer,i,start)
          execute(word3.str)
          sprint(word3.str,"Spikesource%s%g[%g].o(%g).noise=%g",end1,ctr,layer,i,noise)
          execute(word3.str)
          sprint(word3.str,"excit_syn%s%g[%g].append(new ExpSyn(0.5))",end1,ctr,layer)//exponential synapse to apply the stimulus
          execute(word3.str)
          sprint(word3.str,"excit_syn%s%g[%g].o(%g).e=%g",end1,ctr,layer,i,excit_v)
          execute(word3.str)
          sprint(word3.str,"excit_syn%s%g[%g].o(%g).tau=%g",end1,ctr,layer,i,excit_tau)
          execute(word3.str)
          //print word3.str
      }
    }
  }
    
    for ii=0,target_cells.count()-1 {
      if(target_cells.count()-1>0){
        if(cell_type==0){end1="P"}else{if(cell_type==1){end1="FS"}}
        thresh=0 delay=1 Excit_weight=syn_cond //uS
        for(ctr=0;ctr<=sub_idx;ctr+=1){
          sprint(word3.str,"layer%s[%g].o(%g).netcon.append(new NetCon(Spikesource%s%g[%g].o(%g),excit_syn%s%g[%g].o(%g),%g,%g,%g))",end1,layer,ii,end1,ctr,layer,ii,end1,ctr,layer,ii,thresh,delay,Excit_weight)
          execute(word3.str)
          }
        sprint(word3.str,"setup_IC_soma(layer%s[%g],%g,%g,%g,%g,%g)",end1,layer,ii,inf1,max1,cell_type,layer)
        execute(word3.str)
        //print word3.str
        //setup_IC_soma(target_cells,i,inf1,max1,cell_type,layer)
      }
    }
return target_cells 
}
proc setup_IC_soma(){local i,inf, max,unif_rand,cell_type,layer localobj Stim_in
    Stim_in=$o1 i=$2 inf=$3 max=$4 cell_type=$5 layer=$6 unif_rand=rand_gen.uniform(inf,max)  
    word4=new string("")
    strdef end2
    if(cell_type==0){end2="P"}else{if(cell_type==1){end2="FS"}}
    Stim_in.o(i).soma { 
    sprint(word4.str,"Ic%s[%g].append(new IClamp(0.5))",end2,layer)
    execute(word4.str)  
    sprint(word4.str,"Ic%s[%g].o(%g).dur=tstop",end2,layer,i)
    //sprint(word4.str,"Ic%s[%g].o(%g).dur=tstop/2",end2,layer,i)
    execute(word4.str)
    if(cell_type==1){
        sprint(word4.str,"Ic%s[%g].o(%g).amp=%g",end2,layer,i,unif_rand)//=>cell_type =0 for pyramidal population
        execute(word4.str)   
    }else if (cell_type==0){
        sprint(word4.str,"Ic%s[%g].o(%g).amp=%g",end2,layer,i,unif_rand)
        execute(word4.str)}
    //print "The iclamp amplitude is",word4.str//=> cell_type=1 for fs_cell
    sprint(word4.str,"Ic%s[%g].o(%g).del=100",end2,layer,i)
    execute(word4.str)
    /*
    sprint(word4.str,"Ic%s[%g].o(%g).freq=10",end2,layer,i)
    execute(word4.str)*/
     }           
   }