// genesis - sample currents from channels // assume channels already created in {loc_chans} // Output format addglobal str out_form "%0.15g" setclock 2 100 // prevents carriage returns from sim_chan // set voltages: creates tables V_1...V_n (n=nV) of voltages function set_voltage(files) if ({strcmp {files} "none"}) int j, nV={getarg {arglist {files}} -count} for (j=1; j<={nV}; j=j+1) create table "time" call "time" TABCREATE 1 0 1 // default to be overwritten str file = {getarg {arglist {files}} -arg {j}} file2tab {file} "time" table -table2 "dummy" float tdivs = {getfield time table->xdivs} create table "V_"{j} call "V_"{j} TABCREATE 1 0 1 // default to be overwritten setfield "V_"{j} step_mode 2 stepsize 0 file2tab {file} "V_"{j} table -xy {tdivs} echo "set V_"{j}" for" {file} end else echo "voltage not specified in file" end end // output results: output_Ichan <dir> <file> <loc> <var1> <var2> ... function output_Ichan(dir,file,loc) str dir, file, loc if (!{exists {file}}) // create & open asc_file if doesn't exist create asc_file {file} setfield {file} filename {dir}/{file} leave_open 1 append 1 float_format {out_form} call {file} OUT_OPEN // (careful - think acts as toggle) end useclock {file} 1 int i, j, nv=({argc}-3), nchan={countelementlist {loc}/#[CLASS=channel]} for (i=1; i<=nchan; i=i+1) // write header describing channels str channel = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} float Ek={getfield {channel} Ek}, Gbar={getfield {channel} Gbar} float Xp={getfield {channel} Xpower}, Yp={getfield {channel} Ypower} call {file} OUT_WRITE "%" {channel} "Ek" {Ek} "Gbar" {Gbar} "Xpower" {Xp} "Ypower" {Yp} end for (i=1; i<={nchan}; i=i+1) // write header describing vars str channel = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} for (j=1; j<={nv}; j=j+1) str var = {argv {3+j}} call {file} OUT_WRITE "%" {channel} {var} end end for (i=1; i<={nchan}; i=i+1) // add message to asc_file from vars str channel = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} for (j=1; j<={nv}; j=j+1) str var = {argv {3+j}} addmsg {channel} {file} SAVE {var} end end end function addVmsg(Vtable,loc) str Vtable, loc int i, nchan={countelementlist {loc}/#[CLASS=channel]} for (i=1; i<=nchan; i=i+1) str chan = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} addmsg {Vtable} {chan} VOLTAGE output end end function delVmsg(Vtable,loc) str Vtable, loc int i, nchan={countelementlist {loc}/#[CLASS=channel]} for (i=1; i<={nchan}; i=i+1) str chan = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} deletemsg {chan} 0 -incoming -find {Vtable} VOLTAGE end end // output channels: output_XYchan <dir> <file> <loc> function output_XYchan(dir,file,loc) str dir, file, loc if (!{exists {file}}) // create & open asc_file if doesn't exist create asc_file {file} setfield {file} filename {dir}/{file} notime 1 leave_open 1 append 1 float_format {out_form} call {file} OUT_OPEN end useclock {file} 2 // HACK - small clock step avoids carriage returns int i, j, nchan={countelementlist {loc}/#[CLASS=channel]} for (i=1; i<=nchan; i=i+1) // write header describing channels str channel = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} float Ek={getfield {channel} Ek}, Gbar={getfield {channel} Gbar} float Xp={getfield {channel} Xpower}, Yp={getfield {channel} Ypower} call {file} OUT_WRITE "%" {channel} "Ek" {Ek} "Gbar" {Gbar} "Xpower" {Xp} "Ypower" {Yp} end for (i=1; i<=nchan; i=i+1) // loop through channels str channel = {getarg {el {loc}/#[CLASS=channel]} -arg {i}} float X_alloced={getfield {channel} X_alloced}, Y_alloced={getfield {channel} Y_alloced} if (X_alloced) // find voltage range of channel float xmin={getfield {channel} X_A->xmin}, dx={getfield {channel} X_A->dx} float xdivs={getfield {channel} X_A->xdivs} elif (Y_alloced) float xmin={getfield {channel} Y_A->xmin}, dx={getfield {channel} Y_A->dx} float xdivs={getfield {channel} Y_A->xdivs} else // flag up if both X & Y undefined echo {channel} "undefined" return end for (j=0; j<={xdivs}; j=j+1) // loop through voltage vals if (X_alloced) // find X float x_A={getfield {channel} X_A->table[{j}]} float x_B={getfield {channel} X_B->table[{j}]} else str x_A="nan", x_B="nan" end if (Y_alloced) // find Y float y_A={getfield {channel} Y_A->table[{j}]} float y_B={getfield {channel} Y_B->table[{j}]} else str y_A="nan", y_B="nan" end // then write to file call {file} OUT_WRITE {xmin+dx*j} {x_A} {x_B} {y_A} {y_B} end end end //=============================== // Main Script //=============================== // set voltage set_voltage {files_voltage} // Simulation variables float V0 = {getfield V_1 table->table[0]} float tmax = {getfield V_1 table->xmax} float dt = {getfield V_1 table->dx} setclock 1 {dt} // Initial voltage input create table V_0 call V_0 TABCREATE 1 1 1 setfield V_0 step_mode 1 table->table[0] {V0} table->table[1] {V0} // Initialise sim reset setclock 0 {100*dt} addVmsg V_0 {loc_chans} step 100 -t delVmsg V_0 {loc_chans} // Save initial state save {loc_chans}/## {dir_out}/chans.save // Output channel dynamics output_Ichan {dir_out} data_Ik.dat {loc_chans} Ik output_Ichan {dir_out} data_Xk.dat {loc_chans} X output_Ichan {dir_out} data_Yk.dat {loc_chans} Y output_XYchan {dir_out} data_XY.dat {loc_chans} // Run sim int i for (i=1; i<={countelementlist /V_#}-1; i=i+1) reset restore {dir_out}/chans.save addVmsg "V_"{i} {loc_chans} setclock 0 {dt} step {tmax} -t delVmsg "V_"{i} {loc_chans} end quit