//========================================================================================
//=============================== intrinsic manipulations ================================
//========================================================================================

proc addTonicInhibition(){
	forsec $o1.somatic {
		insert tonic
		g_tonic = $2
		e_gaba_tonic = -75
	}
	forsec $o1.basal {
		insert tonic
		g_tonic = $2
		e_gaba_tonic = -75
	}
	if ((strcmp($o1.cell_name, "HL23PYR") == 0) || (strcmp($o1.cell_name, "HL4PYR") == 0) || (strcmp($o1.cell_name, "HL5PYR") == 0) || (strcmp($o1.cell_name, "HL5PN1y") == 0) || (strcmp($o1.cell_name, "HL5PN1o") == 0)){
		forsec $o1.apical {
			insert tonic
			g_tonic = $3
			e_gaba_tonic = -75
		}
	}
}

//========================================================================================
//============================== synapse related functions ===============================
//========================================================================================

// double siteVec[2]
proc createArtificialSyn() {local sitenum,OUni,i localobj sl, postcell, sref
	strdef treename
	postcell = $o2
	
	treename = "dend"
	relpos = 0.5
	sl = postcell.locateSites(treename,relpos*postcell.getLongestBranch(treename))
	for (i=0;i<sl.count();i+=1){
		postcell.siteVec[0] = sl.o[i].x[0]
		postcell.siteVec[1] = sl.o[i].x[1]
		
		access postcell.dend[postcell.siteVec[0]]
		postcell.dend[postcell.siteVec[0]] sref = new SectionRef()
		
		sref {
			postcell.OUprocess.append(new Gfluct2(postcell.siteVec[1]))
			OUni = postcell.OUprocess.count()-1 // OU object index
			// Set OU parameters
			postcell.OUprocess.o[OUni].E_e = 0// time constant of excitatory conductance
			postcell.OUprocess.o[OUni].E_i = -80 // time constant of inhibitory conductance
			postcell.OUprocess.o[OUni].g_e0 = $3*exp(relpos) //0.001*exp(relpos) // average excitatory conductance
			postcell.OUprocess.o[OUni].g_i0 = 0//0.015*exp(relpos) // average inhibitory conductance
			postcell.OUprocess.o[OUni].tau_e = 65 // time constant of excitatory conductance
			postcell.OUprocess.o[OUni].tau_i = 20 // time constant of inhibitory conductance
			postcell.OUprocess.o[OUni].std_e = $3*exp(relpos) //0.001*exp(relpos) // standard dev of excitatory conductance
			postcell.OUprocess.o[OUni].std_i = 0//0.015*exp(relpos) // standard dev of inhibitory conductance
			// OUprocess.o[OUni].new_seed($1*10+i) // This appears to not be threadsafe
			postcell.roulist.append(new Random($1*10+i+5))
			postcell.roulist.o[OUni].normal(0,1)
			postcell.OUprocess.o[OUni].noiseFromRandom(postcell.roulist.o[OUni])
		}
	}
	
	// Apply 5 OUs along apical trunk (if PN)
	if ((strcmp(postcell.cell_name, "HL23PYR") == 0) || (strcmp(postcell.cell_name, "HL4PYR") == 0) || (strcmp(postcell.cell_name, "HL5PYR") == 0) || (strcmp(postcell.cell_name, "HL5PN1y") == 0) || (strcmp(postcell.cell_name, "HL5PN1o") == 0)){
		for (i=0; i<5; i+=1){
			treename = "apic"
			relpos = i*0.2 + 0.1 // [0.1, 0.3, 0.5, 0.7, 0.9]
			sl = postcell.locateSites(treename,relpos*postcell.getLongestBranch(treename))
			
			maxdiam = 0
			for (i1=0; i1<sl.count(); i1+=1){
				dd1 = sl.o[i1].x[1]
				dd = postcell.apic[sl.o[i1].x[0]].diam(dd1)
				if (dd > maxdiam){
					j = i1
					maxdiam = dd
				}
			}
			
			postcell.siteVec[0] = sl.o[j].x[0]
			postcell.siteVec[1] = sl.o[j].x[1]
			
			access postcell.apic[postcell.siteVec[0]]
			postcell.apic[postcell.siteVec[0]] sref = new SectionRef()
			
			sref {
				postcell.OUprocess.append(new Gfluct2(postcell.siteVec[1]))
				OUni = postcell.OUprocess.count()-1 // OU object index
				// Set OU parameters
				postcell.OUprocess.o[OUni].E_e = 0// time constant of excitatory conductance
				postcell.OUprocess.o[OUni].E_i = -80 // time constant of inhibitory conductance
				postcell.OUprocess.o[OUni].g_e0 = $3*exp(relpos) //0.001*exp(relpos) // average excitatory conductance
				postcell.OUprocess.o[OUni].g_i0 = 0//0.015*exp(relpos) // average inhibitory conductance
				postcell.OUprocess.o[OUni].tau_e = 65 // time constant of excitatory conductance
				postcell.OUprocess.o[OUni].tau_i = 20 // time constant of inhibitory conductance
				postcell.OUprocess.o[OUni].std_e = $3*exp(relpos) //0.001*exp(relpos) // standard dev of excitatory conductance
				postcell.OUprocess.o[OUni].std_i = 0//0.015*exp(relpos) // standard dev of inhibitory conductance
				// OUprocess.o[OUni].new_seed($1*10+i) // This appears to not be threadsafe
				postcell.roulist.append(new Random($1*10+i))
				postcell.roulist.o[OUni].normal(0,1)
				postcell.OUprocess.o[OUni].noiseFromRandom(postcell.roulist.o[OUni])
			}
		}
	}
}