// PID function including both original and new clamping styles
// Optional save to file -- set filename to "nosave" to avoid saving
function PID_thresh (location, settle, duration, value, reset_trick, graphics_on, fastclamp, file_name)
float dt = { getclock 0 }
str curr_chan
str local
float original_Em
foreach local ({el {location}})
create PID {local}/pid
setfield {local}/pid cmd {value} gain {1*{getfield {local} Cm}/{dt}} tau_d {{dt}/40} tau_i {{dt}*1e2} saturation 1e-4
if (fastclamp)
setfield {local}/pid cmd {value} gain 0.25e-6 tau_d {{dt}/4} tau_i {{dt}} saturation 1e-4
end
addmsg {local} {local}/pid SNS Vm
addmsg {local}/pid {local} INJECT output
create compartment {local}/integral
setfield {local}/integral Vm 0 Em 0 Cm 1 Rm {{duration}*1000} // Make sure decay constant is 10 times duration (very low)
addmsg {local}/pid {local}/integral INJECT output // This will integrate the total output
end
// // Plotting
//create xform /formpid
//create xgraph /formpid/graph
//addmsg {local}/pid /formpid/graph PLOT output *value *blue
//addmsg {local}/integral /formpid/graph PLOT Vm *integral *red
//xshow /formpid
// Write to file
if ( file_name != "nosave" )
create asc_file {file_name}
setfield ^ flush 0 leave_open 1 append 0 notime 0 float_format %0.10g filename {dataoutput_path}{file_name}
useclock ^ 1
addmsg {local}/pid {file_name} SAVE output
end
//Plotting // Adds a line to the exisitng "graphs1/Ik" plotting forum
if (graphics_on == 1)
str dest_plot = "/graphs1"
addmsg {local}/pid {{dest_plot} @ "/Ik"} PLOT output *PID *red
end
if ( reset_trick ) // Generally good not to use this, since
// it produces an unexplainable kink in the
// output.... (probably a bug)
setfield /#/#/#[TYPE=compartment] Em {value}
reset
reset // Get channels into correct equilibrium state
setfield /#/#/#[TYPE=compartment] Em -0.060 Vm {value}
//From looking at the Im plot, it appears that this
//kink is caused by some abrupt change in the axial
//current, possibly caused by a discontinuity in a
//dendrite upstream of the soma (integrator problem)
else
reset
reset
end
step {round { {settle}/{dt} }}
foreach local ({el {location}})
setfield {local}/integral Vm 0
end
step {round { {duration}/{dt} }}
foreach local ({el {location}})
echo setfield {local} inject {{getfield {local}/integral Vm} / {duration}}
echo Current PID value: {getfield {local}/pid output}
setfield {local} inject {{getfield {local}/integral Vm} / {duration}}
// setfield /fb_array/fb[1]/soma inject {{getfield {local}/integral Vm} / {duration}}
//setfield {local} inject {getfield {local}/pid output}
// if (!ploton)
delete {local}/pid
delete {local}/integral
// end
end
//reset
//reset
end