// processes and functions 

//fixing nseg number of compartments for the spatial discretization

// these are reasonable values for most models
freq = 100      // Hz, frequency at which AC length constant will be computed
d_lambda = 0.1

func lambda_f() { local i, x1, x2, d1, d2, lam
        if (n3d() < 2) {
                return 1e5*sqrt(diam/(4*PI*$1*user_Ra*user_cm))
        }
// above was too inaccurate with large variation in 3d diameter
// so now we use all 3-d points to get a better approximate lambda
        x1 = arc3d(0)
        d1 = diam3d(0)
        lam = 0
        for i=1, n3d()-1 {
                x2 = arc3d(i)
                d2 = diam3d(i)
                lam += (x2 - x1)/sqrt(d1 + d2)
                x1 = x2   d1 = d2
        }
        //  length of the section in units of lambda
        lam *= sqrt(2) * 1e-5*sqrt(4*PI*$1*user_Ra*user_cm)

        return L/lam
}

//initializing the simulation

proc init(){

	forall{
		for(x,0){
			Ra = user_Ra
			v = 0
			cm = user_cm
			g_pas = user_g_pas
			e_pas = user_e_pas
			v_init = 0
		}
	}

	setNseg()
	
	finitialize(v_init)
    if (cvode.active()) {
      cvode.re_init()
    } else {
      fcurrent()
    }
    frecord_init()
}

proc setNseg(){

	soma area(0.5) // make sure diam reflects 3d points
	forsec all_1 {
		nseg = int((L/(d_lambda*lambda_f(freq))+0.9)/2)*2 + 1
	}
}

//Setting dt

proc setdt() {local Dt, dtnew
	if (using_cvode_) return
	Dt = 1/steps_per_ms
	nstep_steprun = int(Dt/dt)
	if (nstep_steprun == 0) {
		nstep_steprun = 1
	}
	dtnew = Dt/nstep_steprun
	if (abs(dt*nstep_steprun*steps_per_ms - 1) > 1e-6) {
		print "Changed dt"
		dt = dtnew
	}
}

//Setting the screen update interval

proc continuerun() {local rt, rtstart, ts
	realtime = 0  rt = screen_update_invl  rtstart = startsw()
	eventcount=0
	eventslow=1
	stoprun = 0
	if (using_cvode_) {
		cvode.event($1)
		ts = $1
		if (cvode.use_local_dt) {
			cvode.solve(ts)
			flushPlot()
			realtime = startsw() - rtstart
			return
		}
	}else{
		ts = $1 - dt/2
	}
	while(t < ts && stoprun == 0) {
		step()
		realtime = startsw() - rtstart
		if (realtime >= rt) {
//			if (!stdrun_quiet) fastflushPlot()
			screen_update()
			//really compute for at least screen_update_invl
			realtime = startsw() - rtstart
			rt = realtime + screen_update_invl
		}
	}
	if (using_cvode_ && stoprun == 0) { // handle the "tstop" event
		step() // so all recordings take place at tstop
	}
	flushPlot()
	realtime = startsw() - rtstart
}


//Possibility to choose between the integration methods

proc cvode_act(){
	if (isCVodeAct){
		cvode.active(1)
		
		print "Using variable time step integration method - faster simulation"
	} else{
		cvode.active(0)
		
		print "Using fix time step integration method - slower simulation"
	}
}

proc injSoma(){

	isStim1 = 1
	isStim2 = 0

	stim1.amp = 0.1
	stim2.amp = 0.02
	stim3.amp = 0
	stim4.amp = 0
}

proc injDend(){

	isStim1 = 0
	isStim2 = 1

	access dend[19]{
		stim3.loc(0.971)					
		stim4.loc(0.971)					
	}

	stim1.amp = 0
	stim2.amp = 0
	stim3.amp = 0.1
	stim4.amp = 0.02
}