// Artificial cells no longer need a default section.
//Network cell templates
//   HHCell_Cell
//Artificial cells
//   IntFire4_IntFire4
//   NetStim_NetStim


begintemplate HHCell_Cell
public is_art
public init, topol, basic_shape, subsets, geom, biophys, geom_nseg, biophys_inhomo
public synlist, x, y, z, position, connect2target

public soma
public all

objref synlist

proc init() {
  topol()
  subsets()
  geom()
  biophys()
  geom_nseg()
  synlist = new List()
  synapses()
  x = y = z = 0 // only change via position
}

create soma

proc topol() { local i
  basic_shape()
}
proc basic_shape() {
  soma {pt3dclear() pt3dadd(0, 0, 0, 1) pt3dadd(15, 0, 0, 1)}
}

objref all
proc subsets() { local i
  objref all
  all = new SectionList()
    soma all.append()

}
proc geom() {
  soma {  L = 16  diam = 16  }
}
external lambda_f
proc geom_nseg() {
  soma { nseg = int((L/(0.1*lambda_f(100))+.9)/2)*2 + 1  }
}
proc biophys() {
  soma {
    Ra = 100
    cm = 1
    //insert pas
    //  g_pas = 0.005
    //  e_pas = -70
    insert hh
      gnabar_hh = 0.12
      gkbar_hh = 0.036
      gl_hh = 0.0003
      el_hh = -54.3
  }
}
proc biophys_inhomo(){}
proc position() { local i
  soma for i = 0, n3d()-1 {
    pt3dchange(i, $1-x+x3d(i), $2-y+y3d(i), $3-z+z3d(i), diam3d(i))
  }
  x = $1  y = $2  z = $3
}
obfunc connect2target() { localobj nc //$o1 target point process, optional $o2 returned NetCon
  soma nc = new NetCon(&v(1), $o1)
  nc.threshold = 10
  if (numarg() == 2) { $o2 = nc } // for backward compatibility
  return nc
}
objref syn_
proc synapses() {
  /* GABA0 */   soma syn_ = new ExpSyn(0.7)  synlist.append(syn_)
    syn_.tau = 5
    syn_.e = -70
  /* AMPA1 */   soma syn_ = new ExpSyn(0.6)  synlist.append(syn_)
    syn_.tau = 1
}
func is_art() { return 0 }

endtemplate HHCell_Cell

begintemplate IntFire4_IntFire4
public pp, connect2target, x, y, z, position, is_art
objref pp
proc init() {
  pp = new IntFire4()
    pp.taue = 1
    pp.taui1 = 1
    pp.taui2 = 5
}

func is_art() { return 1 }
obfunc connect2target() { localobj nc
  nc = new NetCon(pp, $o1)
  if (numarg() == 2) { $o2 = nc }
  return nc
}
proc position(){x=$1  y=$2  z=$3}
endtemplate IntFire4_IntFire4

begintemplate NetStim_NetStim
public pp, connect2target, x, y, z, position, is_art
objref pp
proc init() {
  pp = new NetStim()
    pp.noise = 1
}
func is_art() { return 1 }
obfunc connect2target() { localobj nc
  nc = new NetCon(pp, $o1)
  if (numarg() == 2) { $o2 = nc }
  return nc
}
proc position(){x=$1  y=$2  z=$3}
endtemplate NetStim_NetStim

//Network specification interface

objref cells, nclist, netcon
{cells = new List()  nclist = new List()}

func cell_append() {cells.append($o1)  $o1.position($2,$3,$4)
	return cells.count - 1
}

func nc_append() {//srcindex, tarcelindex, synindex
  if ($3 >= 0) {
    netcon = cells.object($1).connect2target(cells.object($2).synlist.object($3))
    netcon.weight = $4   netcon.delay = $5
  }else{
    netcon = cells.object($1).connect2target(cells.object($2).pp)
    netcon.weight = $4   netcon.delay = $5
  }
  nclist.append(netcon)
  return nclist.count - 1
}

//Network instantiation
//Stimuli
objref NetStimList, ArtCell
NetStimList=new List()

	/* NetStim0 */
    ArtCell=new NetStim_NetStim()
	NetStimList.append(ArtCell.pp)
	cell_append(ArtCell,	-104,	 27, 0)
	
	/* NetStim1 */
    ArtCell=new NetStim_NetStim()
	NetStimList.append(ArtCell.pp)
	cell_append(ArtCell,	0,	 27, 0)

//Artificial Cells
objref ArtCellList, ArtCell
ArtCellList=new List()
	/* IntFire42 */
    ArtCell=new IntFire4_IntFire4()
	ArtCellList.append(ArtCell.pp)
	cell_append(ArtCell,	-107,	 -27, 0)
	/* IntFire43 */ 
	ArtCell=new IntFire4_IntFire4()
	ArtCellList.append(ArtCell.pp)
	cell_append(ArtCell,	-6,	 -30, 0)

// Conductance based cell models
objref HHCellList
HHCellList=new List()

 	 /* HHCell4 */  
	HHCellList.append(new HHCell_Cell())
	cell_append(HHCellList.o(0),	-107,	 -73, 0)
  	/* HHCell5 */  
	HHCellList.append(new HHCell_Cell())
	cell_append(HHCellList.o(1),	-13,	 -74, 0)


  /* NetStim0 -> IntFire42    */  nc_append(0, 2, -1,  1,1)
  /* NetStim1 -> IntFire43    */  nc_append(1, 3, -1,  1,1)


  /* IntFire43 -> HHCell5.AMPA1 */  nc_append(3,   5, 1,  0.5,1)
  /* IntFire43 -> HHCell4.GABA0 */  nc_append(3,   4, 0,  0.5,1)

  /* IntFire42 -> HHCell4.AMPA1 */  nc_append(2,   4, 1,  0.5,1)
  /* IntFire42 -> HHCell5.GABA0 */  nc_append(2,   5, 0,  0.5,1)

// Add graph
objectvar save_window_, rvp_
objectvar scene_vector_[3]
objectvar ocbox_, ocbox_list_, scene_, scene_list_
{ocbox_list_ = new List()  scene_list_ = new List()}
{
save_window_ = new Graph(0)
save_window_.size(0,500,-80,400)
scene_vector_[2] = save_window_
{save_window_.view(0, -80, 500, 480, 26, 334, 600, 400)}
graphList[0].append(save_window_)
save_window_.save_name("graphList[0].")
save_window_.addexpr("HHCell_Cell[0].soma.v( 0.5 )", 1, 1, 0.8, 0.9, 2)
//save_window_.addexpr("0", 1, 1, 0.8, 0.9, 2)

save_window_.addexpr("HHCell_Cell[1].soma.v( 0.5 )+100", 2, 1, 0.8, 0.9, 2)
//save_window_.addexpr("100", 2, 1, 0.8, 0.9, 2)

save_window_.addexpr("100*IntFire4_IntFire4[0].pp.M+200", 3, 1, 0.8, 0.9, 2)
save_window_.addexpr("100*IntFire4_IntFire4[1].pp.M+300", 4, 1, 0.8, 0.9, 2)

}
objectvar scene_vector_[1]
{doNotify()}

// Add ordinary runcontrol
tstop=500
nrncontrolmenu()
tstop_changed()

objref ImpedanceTool
func getic(){local ic
    HHCellList.o(0).soma {
        ImpedanceTool=new Impedance()
        ImpedanceTool.loc(0.5)
        ImpedanceTool.compute(0)
        ic=1/ImpedanceTool.input(0.5)    // Input conductance in micro Siemens
    }

    objref ImpedanceTool
    return ic
}

objref SomaticSections
SomaticSections=new SectionList()
forsec "soma" {SomaticSections.append()}



create cellbody
create dend1[3]
create dend2[3]
cellbody {
    connect dend1[0](0), 1
    connect dend2[0](0), 1
  }
  
for j=0,1 {
  connect dend1[j+1](1), dend1[j](0)
  connect dend2[j+1](1), dend2[j](0) 
}

cellbody {  
  Ra = 100
  cm = 1
  insert hh
  gnabar_hh = 0.12
  gkbar_hh = 0.012
  gl_hh = 0.0003
  el_hh = -54.3
  L = 16
  diam = 16
  nseg=1
}

forsec "dend1"{
  Ra = 100
  cm = 1
  insert hh
  gnabar_hh = 0.012
  gkbar_hh = 0.036
  gl_hh = 0.003
  el_hh = -54.3
  L = 50
  diam = 1
  nseg=5
}


forsec "dend2"{
  Ra = 100
  cm = 1
  insert hh
  gnabar_hh = 0.012
  gkbar_hh = 0.036
  gl_hh = 0.003
  el_hh = -54.3
  L = 50
  diam = 1
  nseg=5
}


objref syn1,syn2, ncsyn1,ncsyn2
dend1[0] {
  syn1=new ExpSyn(1)
}
syn1.e=50

ncsyn1= new NetCon(NetStimList.o(0),syn1)
ncsyn1.weight=5

dend2[1] {
  uninsert hh
  L=300
  nseg=30
  syn2=new ExpSyn(1)
}
ncsyn2= new NetCon(NetStimList.o(1),syn2)
syn2.e=50
ncsyn2.weight=5

objectvar save_window_, rvp_
objectvar scene_vector_[4]
objectvar ocbox_, ocbox_list_, scene_, scene_list_
{ocbox_list_ = new List()  scene_list_ = new List()}
{
save_window_ = new Graph(0)
save_window_.size(0,500,-80,40)
scene_vector_[3] = save_window_
{save_window_.view(0, -80, 500, 120, 73, 246, 300.48, 200.32)}
graphList[0].append(save_window_)
save_window_.save_name("graphList[0].")
save_window_.addexpr("cellbody.v(.5)", 1, 1, 0.8, 0.9, 2)
save_window_.addexpr("dend1[0].v(.5)", 2, 6, 0.8, 0.9, 2)
save_window_.addexpr("dend1[1].v(.5)", 2, 7, 0.8, 0.9, 2)
save_window_.addexpr("dend1[2].v(.5)", 2, 8, 0.8, 0.9, 2)
save_window_.addexpr("dend2[0].v(.5)", 3, 6, 0.8, 0.9, 2)
save_window_.addexpr("dend2[1].v(.5)", 3, 7, 0.8, 0.9, 2)
save_window_.addexpr("dend2[2].v(.5)", 3, 8, 0.8, 0.9, 2)
}
objectvar scene_vector_[1]
{doNotify()}


objref myIClamp
cellbody {myIClamp=new IClamp(0)}
myIClamp.amp=0.2
myIClamp.dur=tstop
myIClamp.del=100

access cellbody