begintemplate pvbasketcell
 public variables

public  pre_list, connect_pre, append_sections, is_art, is_connected, gid, randi
public soma, bcdendAP1, bcdendAP2, bcdendBAS1, bcdendBAS2
public all, adend, bdend, cdend, ddend, basal_list, apical_list, soma_list, axon_list
public x, y, z, position, myroot

public pyramidalcell_list, axoaxoniccell_list, bistratifiedcell_list, cckcell_list, deepcell_list, supercell_list
public ivycell_list, ngfcell_list, olmcell_list, pvbasketcell_list, scacell_list
public eccell_list, ca3cell_list, mscell_list, stimcell_list

// strings
strdef myroot

// objects
objref syn, pre_list, templist, rootlist

// external variables
external numCellTypes, cellType

// create the sections[nsegments]
// if nsegments (the number of segments in each section) is updated,
// you'll have to manually change the bounds on the for loops as well
create soma, bcdendAP1[4], bcdendAP2[4], bcdendBAS1[4], bcdendBAS2[4]

// set the initialization code, which is run whenever a new object
// of this class is instantiated
proc init() {
	gid = $1
	randi = $2
	// cell sections: soma, dendrites, axon
	append_sections() // append all sections to the section list
	connect_sections()// connect soma, dendrites, axon
	size_sections()	// set the size dimensions of each section
	set_nseg()		// set the number of segments in each section
	
	// subcellular mechanisms: channels, pumps, transporters
	mechinit()
	insert_mechs()

	define_shape()
	get_root()

	pre_list = new List() // define a list for the presynaptic connections
	define_synapses()
}

objref all, adend, bdend, cdend, ddend // this is also defined later, in a fcn. which place should it be defined?
proc connect_sections() { local i
	connect bcdendAP1[0](0), soma(1)
	connect bcdendAP2[0](0), soma(1)
	connect bcdendBAS1[0](0), soma(0)
	connect bcdendBAS2[0](0), soma(0)
	for i=1, 3 { // upper bound is # of segments - 1
	connect bcdendAP1[i](0), bcdendAP1[i-1](1)
	}
	for i=1, 3 { // upper bound is # of segments - 1
	connect bcdendAP2[i](0), bcdendAP2[i-1](1)
	}
	for i=1, 3 { // upper bound is # of segments - 1
	connect bcdendBAS1[i](0), bcdendBAS1[i-1](1)
	}
	for i=1, 3 { // upper bound is # of segments - 1
	connect bcdendBAS2[i](0), bcdendBAS2[i-1](1)
	}
}

objref basal_list, apical_list, soma_list, axon_list
objref pyramidalcell_list, axoaxoniccell_list, bistratifiedcell_list, cckcell_list, deepcell_list, supercell_list
objref ivycell_list, ngfcell_list, olmcell_list, pvbasketcell_list, scacell_list
objref eccell_list, ca3cell_list, mscell_list, stimcell_list
proc append_sections() { local i
	objref all, basal_list, apical_list, soma_list, axon_list
	objref pyramidalcell_list, axoaxoniccell_list, bistratifiedcell_list, cckcell_list, deepcell_list, supercell_list
	objref ivycell_list, ngfcell_list, olmcell_list, pvbasketcell_list, scacell_list
	objref eccell_list, ca3cell_list, mscell_list, stimcell_list

	pyramidalcell_list = new SectionList()
	deepcell_list = new SectionList()
	supercell_list = new SectionList()
	axoaxoniccell_list = new SectionList()
	bistratifiedcell_list = new SectionList()
	cckcell_list = new SectionList()
	ivycell_list = new SectionList()
	ngfcell_list = new SectionList()
	olmcell_list = new SectionList()
	pvbasketcell_list = new SectionList()
	scacell_list = new SectionList()
	eccell_list = new SectionList()
	ca3cell_list = new SectionList()
	stimcell_list = new SectionList()
	mscell_list = new SectionList()
	// Make a list for every section in the cell
	all = new SectionList()	
  basal_list = new SectionList()
  apical_list = new SectionList()
  soma_list = new SectionList()
  axon_list = new SectionList()
  
		soma all.append()
		soma soma_list.append()
		for i=0, 3 {bcdendAP1 [i] all.append()
					bcdendAP1 [i] apical_list.append()}
		for i=0, 3 {bcdendAP2 [i] all.append()
					bcdendAP2 [i] apical_list.append()}
		for i=0, 3 {bcdendBAS1 [i] all.append()
					bcdendBAS1 [i] basal_list.append()}
		for i=0, 3 {bcdendBAS2 [i] all.append()
					bcdendBAS2 [i] basal_list.append()}

	// Make lists of dendrite sections that
	//  are all the same relative distance
	//  from the soma (useful when adding ion channels)
	// The code in this section will have to be customized
	//  depending on how detailed (and different) the sections
	//  are for each main dendrite
	adend  = new SectionList()	
		bcdendAP1 [0] adend.append()
		bcdendAP2 [0] adend.append()
		bcdendBAS1 [0] adend.append()
		bcdendBAS2 [0] adend.append()

	bdend  = new SectionList()
		bcdendAP1 [1] bdend.append()
		bcdendAP2 [1] bdend.append()
		bcdendBAS1 [1] bdend.append()
		bcdendBAS2 [1] bdend.append()

	cdend  = new SectionList()
		bcdendAP1 [2] cdend.append()
		bcdendAP2 [2] cdend.append()
		bcdendBAS1 [2] cdend.append()
		bcdendBAS2 [2] cdend.append()

	ddend  = new SectionList()
		bcdendAP1 [3] ddend.append()
		bcdendAP2 [3] ddend.append()
		bcdendBAS1 [3] ddend.append()
		bcdendBAS2 [3] ddend.append()

// cell lists
		for i=0, 1 {
			bcdendAP1 [i] scacell_list.append()
			bcdendAP2 [i] scacell_list.append()
		}
		for i=0, 3 {
			bcdendBAS1 [i] scacell_list.append()
			bcdendBAS2 [i] scacell_list.append()
		}

		for i=0, 3 {
			bcdendBAS1 [i] pyramidalcell_list.append()
			bcdendBAS2 [i] pyramidalcell_list.append()
		}

		for i=0, 3 {
			bcdendBAS1 [i] deepcell_list.append()
			bcdendBAS2 [i] deepcell_list.append()
		}

		for i=0, 3 {
			bcdendBAS1 [i] supercell_list.append()
			bcdendBAS2 [i] supercell_list.append()
		}

		for i=2, 3 {
			bcdendAP1 [i] eccell_list.append()
			bcdendAP2 [i] eccell_list.append()
		}

		for i=0, 1 {
			bcdendAP1 [i] ca3cell_list.append()
			bcdendAP2 [i] ca3cell_list.append()
		}
		
		forsec soma_list {pvbasketcell_list.append()}
		
		forsec soma_list {stimcell_list.append()}
		
		forsec soma_list {cckcell_list.append()}

		for i=2, 3 {
			bcdendAP1 [i] ngfcell_list.append()
			bcdendAP2 [i] ngfcell_list.append()
		}

		for i=0, 3 {
			bcdendBAS1 [i] olmcell_list.append()
			bcdendBAS2 [i] olmcell_list.append()
		}

		for i=0, 1 {
			bcdendAP1 [i] ivycell_list.append()
			bcdendAP2 [i] ivycell_list.append()
		}
		for i=0, 3 {
			bcdendBAS1 [i] ivycell_list.append()
			bcdendBAS2 [i] ivycell_list.append()
		}

		for i=0, 1 {
			bcdendAP1 [i] bistratifiedcell_list.append()
			bcdendAP2 [i] bistratifiedcell_list.append()
		}
		for i=0, 3 {
			bcdendBAS1 [i] bistratifiedcell_list.append()
			bcdendBAS2 [i] bistratifiedcell_list.append()
		}
}

proc size_sections() { local i
	soma {L=20 diam=15}
	for i=0, 3 { // upper bound is # of segments - 1
		bcdendAP1 [i] {L=75 diam=4-i}
	}	
	for i=0, 3 { // upper bound is # of segments - 1
		bcdendAP2 [i] {L=75 diam=4-i}
	}	
	for i=0, 3 { // upper bound is # of segments - 1
		bcdendBAS1 [i] {L=50 diam=4-i}
	}	
	for i=0, 3 { // upper bound is # of segments - 1
		bcdendBAS2 [i] {L=50 diam=4-i}
	}
}

external lambda_f
proc set_nseg() {
  	forsec all { nseg = int((L/(0.1*lambda_f(100))+.9)/2)*2 + 1  }
}
proc mechinit() {
	// Temperature of simulation
	celsius = 34.0  
	
	// Membrane capacitance in uF/cm2
	CmAll = 1.4

	// Axial resistance in ohm*cm
	RaAll = 100	

	// reversal potentials in mV
	ekval = -90
	ecaval = 130
	enaval = 55
	eleakval = -60.06

	// Sodium channel voltage shift in mV
	vshift = -8
	
	// Calcium concentrations in mM
	ca_outside = 2
	ca_inside = 5.e-6
	
	// max ion channel conductances in mho/cm2
	gleak = 0.00030 // leak channel conductance
	gNav = 0.12 // Voltage gated sodium
	gKvA=0.00015 // A-type potassium
	gKdrfast=0.013 // Fast delayed rectifier potassium
	gKvCaB=0.0002 // Big potassium channel: voltage and calcium gated
	gKCaS=0.000002 // Small potassium channel: calcium gated
	gCavL=0.005 // L-type calcium
	gCavN=0.0008 // N-type calcium
}
proc insert_mechs() {
	forsec all {
		Ra=RaAll		// Ra = Axial resistivity in ohm-cm. Ra is a
					//  section variable that must be set for each
					//  section. Default is 35.4.
	
		cm=CmAll		// capacitance in uF/cm^2. default = 1.0
		
		insert iconc_Ca
			catau_iconc_Ca = 10
			caiinf_iconc_Ca = ca_inside
			cao_iconc_Ca=ca_outside
		insert ch_KvA
			gmax_ch_KvA=gKvA
		insert ch_CavN
			gmax_ch_CavN=gCavN  
		insert ch_CavL 
			gmax_ch_CavL=gCavL
		insert ch_KCaS
			gmax_ch_KCaS= gKCaS
		insert ch_KvCaB
			gmax_ch_KvCaB= gKvCaB
		insert ch_leak
			gmax_ch_leak = gleak
	
		ek=ekval  
		elca=ecaval	
		e_ch_leak =eleakval
	}

	soma {		
		insert ch_NavPVBC
			gmax_ch_NavPVBC= gNav 
			ena = enaval 
			vshift_ch_NavPVBC = vshift
		insert ch_Kdrfast
			gmax_ch_Kdrfast=gKdrfast  
	} 

	forsec adend {
		insert ch_NavPVBC
			gmax_ch_NavPVBC= gNav
			ena = enaval 
			vshift_ch_NavPVBC = vshift
		insert ch_Kdrfast
			gmax_ch_Kdrfast=gKdrfast
	}		
}



proc connect_pre() {  // $o1 target point process, $o2 returned NetCon
	soma $o2 = new NetCon (&v(1), $o1)
		 $o2.threshold = -10 //except for bcell to bcell, which is -10???
}

func is_art()  { return 0 }

proc position(){ local i
		forall {
		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	
}	

proc get_root() {local i localobj sref
	rootlist = new SectionList()
	rootlist.allroots()
	i=0
	forsec all {
		sref = new SectionRef()
		if (sref.has_parent==0) {
			myroot = secname()
			i=i+1
		}
	}
	if (i>1) {
		print "WARNING: cell ", gid, " has ", i, " root sections!"
	}
}

objref syn  
proc define_synapses() {local i localobj f2, f3

}
endtemplate pvbasketcell