begintemplate RunFitParm
public name, val, low, high, doarg, invalid, copy, set, play_one
public setln, getln, uselog, domain, domain_, setname, pval
strdef name, domain_
objref pval
proc init() {
uselog = 0
set($s1, 1, -1e6, 1e6, 1, 0)
}
proc set() {
setname($s1)
val = $2
low = $3
high = $4
doarg = $5
uselog = $6
domain()
}
proc setname() {
name = $s1
if (strcmp(name, "") != 0) {
pval = new Pointer(&val, name)
}else{
objref pval
}
}
proc domain() {
if (uselog && ((low > 0) || (high < 0))) {
sprint(domain_, " X %g %g %s", low, high, name)
}else{
sprint(domain_, " %g %g %s", low, high, name)
}
}
proc copy() {
set($o1.name, $o1.val, $o1.low, $o1.high, $o1.doarg, $o1.uselog)
}
func invalid() {
if (val < low || val > high) {
return 1
}
return 0
}
proc play_one() {
pval.assign(val)
}
proc setln() {
if (uselog) {
if (low > 0) {
val = exp($1)
}else if (high < 0) {
val = -exp($1)
}else{
val = $1
}
}else{
val = $1
}
}
func getln() {
if (uselog) {
if (low > 0) {
return log(val)
}else if (high < 0) {
return log(-val)
}
return val
}else{
return val
}
}
endtemplate RunFitParm
begintemplate GenInfo
public gen, use, s, toggle
objref gen
strdef s
proc init() {
gen = $o1
if (numarg() > 1) {
use = $o2.scanvar
}else{
use = 0
}
use = (use + 1) % 2
toggle()
}
proc toggle() {
use = (use+1)%2
if (use) {
sprint(s, "+ %s", gen.title)
}else {
sprint(s, "- %s", gen.title)
}
}
endtemplate GenInfo
begintemplate ParmFitness
public parmlist, efun, doarg_get, generatorlist, title, errval, pc
public rfile, wfile, usegen, parmlist_use, putall, argget, randomize
public use_parallel, save_context, declare
public randomize_inrange
external classname
objref parmlist, generatorlist, tobj, sf, this, usegen, parmlist_use
objref ran, pc, parmvec
strdef title, tstr, tstr1
func efun() {local e, i
if (use_parallel_) {
return efun_parallel($1, &$&2)
}
for i=0, $1-1 {
tobj = parmlist_use.object(i)
tobj.setln($&2[i])
if (tobj.invalid) {
printf("invalid %s low=%g val=%g high=%g\n", tobj.name, tobj.low, tobj.val,tobj.high)
return 1e9
}
tobj.play_one()
}
e = 0
for i=0, generatorlist.count-1 {
if (generatorlist.object(i).use) {
e += generatorlist.object(i).gen.efun()
if (stoprun) {break}
}
}
errval = e
return e
}
func parm() {local i
for i=0, $o1.size-1 {
tobj = parmlist_use.object(i)
tobj.setln($o1.x[i])
if (tobj.invalid) {
printf("invalid %s low=%g val=%g high=%g\n", tobj.name, tobj.low, tobj.val,tobj.high)
return 0
}
tobj.play_one()
}
return 1
}
func efun1() {
if ($3 != context_) {
printf("%s bad context: mine=%d needed=%d\n", \
this, context_, $3)
quit()
}
parm($o2)
return generatorlist.object($1).gen.efun()
}
func efun_parallel() {local e, i, j, n, b
if (parm(parmvec.from_double($1, &$&2)) == 0) {
return 1e9
}
n = generatorlist.count
for j=0, n - 1 {
if (generatorlist.object(j).use) {
break
}
}
b = 0
for i=j+1, n-1 {
if (generatorlist.object(i).use) {
pc.submit(this, "efun1", i, parmvec, context_)
b = 1
}
}
if (j < n) {
e = generatorlist.object(j).gen.efun()
}
if (b) {
while (pc.working()) {
e += pc.retval
}
}
errval = e
return e
}
proc save_context() {local i
context_ += 1
sprint(tstr, "%s", this)
pc.look_take(tstr)
pc.pack(title, context_)
pc.pack(generatorlist.count)
for i=0, generatorlist.count-1 {
tobj = generatorlist.object(i)
classname(tobj.gen, tstr)
pc.pack(tstr)
tobj.gen.save_context(pc)
pc.pack(tobj.use)
}
pc.pack(parmlist.count)
for i=0, parmlist.count-1 {
tobj = parmlist.object(i)
pc.pack(tobj.name, tobj.val, tobj.low, tobj.high, \
tobj.doarg, tobj.uselog)
}
sprint(tstr, "%s", this)
pc.post(tstr)
pc.context(this, "restore_context", tstr)
}
proc restore_context() {local i, n
pc.look($s1)
pc.unpack(title, &context_)
generatorlist.remove_all
n = pc.upkscalar
for i=0, n-1 {
pc.upkstr(tstr)
sprint(tstr, "tobj = new GenInfo(new %s())", tstr)
execute(tstr, this)
tobj.gen.restore_context(pc)
if (pc.upkscalar == 1) tobj.toggle()
generatorlist.append(tobj)
}
parmlist.remove_all
n = pc.upkscalar
for i=0, n-1 {
tobj = new RunFitParm(pc.upkstr(tstr))
pc.unpack(&tobj.val, &tobj.low, &tobj.high, \
&tobj.doarg, &tobj.uselog)
tobj.domain()
declare(tobj)
tobj.play_one()
parmlist.append(tobj)
}
def_parmlist_use()
}
proc use_parallel() {
if ($1 == 1) {
save_context()
}
use_parallel_ = $1
}
proc init() {
context_ = 1
use_parallel_ = 0
if (numarg() > 0) {
title = $s1
}
// "this" is the stable context (all publics and descendants)
pc = new ParallelContext()
parmvec = new Vector()
parmlist = new List()
parmlist_use = new List()
generatorlist = new List()
sf = new StringFunctions()
}
proc randomize() { local i, x
if (object_id(ran) == 0) {
ran = new Random(startsw())
}
if ($1 <= 0) return
ran.uniform(-log($1),log($1))
for i=0, parmlist.count-1 {
tobj = parmlist.object(i)
if (tobj.doarg) {
x = tobj.val * exp(ran.repick)
tobj.val = x
tobj.play_one()
}
}
}
proc randomize_inrange() { local i, x
if (object_id(ran) == 0) {
ran = new Random(startsw())
}
if ($1 <= 0) return
ran.uniform(-log($1),log($1))
for i=0, parmlist.count-1 {
tobj = parmlist.object(i)
if (tobj.doarg) {
x = tobj.pval * exp(ran.repick)
//x = tobj.val * exp(ran.repick)
while( x < tobj.low || x > tobj.high ) {
print "\t",x, " out of range [",tobj.low,", ",tobj.high, "] -- repick"
x = tobj.pval * exp(ran.repick)
//x = tobj.val * exp(ran.repick)
//print "\t",x, " new value"
}
//print x, " is IN range [",tobj.low,", ",tobj.high, "]"
tobj.pval = x
//tobj.val = x
//tobj.play_one()
}
}
}
proc def_parmlist_use() {local i
parmlist_use.remove_all()
for i=0, parmlist.count-1 {
if (parmlist.object(i).doarg) {
parmlist_use.append(parmlist.object(i))
//printf("def_parmlist_use %d %s\n", i, parmlist.object(i).name)
}
}
}
func doarg_get() {local i, n
def_parmlist_use()
n = parmlist_use.count
$o1.resize(n)
for i=0, n-1 {
$o1.x[i] = parmlist_use.object(i).getln()
}
return n
}
proc argget() {local i
j = 0
$o1.resize(parmlist.count)
for i=0, parmlist.count-1 {
$o1.x[i] = parmlist.object(i).val
}
}
proc putall() {local i
for i=0, parmlist.count-1 {
parmlist.object(i).play_one()
}
}
proc wfile() {local i
$o1.printf("ParmFitness: %s\n", title)
for i=0, generatorlist.count-1 {
generatorlist.object(i).gen.wfile($o1, $o2)
$o2.printf("%d\n", generatorlist.object(i).use)
}
$o1.printf("\tParameters:\n")
for i=0, parmlist.count-1 {
tobj = parmlist.object(i)
$o1.printf("\t\t\"%s\", %g, %g, %g, %g, %g\n", tobj.name,\
tobj.val, tobj.low, tobj.high, tobj.doarg, tobj.uselog)
}
$o1.printf("End ParmFitness\n")
}
proc rfile() {local use
if (numarg() == 3) {
tstr = $s3
}else{
$o1.gets(tstr)
}
sscanf(tstr,"ParmFitness: %[^\n]", title)
// Read the FitnessGenerators information
while (1) {
$o1.gets(tstr)
if (sf.len(tstr) == 1) continue
sscanf(tstr, "%[^:]:", tstr1)
if (sf.substr(tstr1, "Parameters") > -1) break
sprint(tstr1, "tobj = new %s(0)", tstr1)
execute(tstr1, this)
tobj.rfile($o1, $o2, tstr)
//printf("%s %s\n", tobj, tobj.title)
generatorlist.append(new GenInfo(tobj, $o2))
}
// Read the Parameters information
while (1) {
$o1.gets(tstr)
if (sf.substr(tstr, "End ParmFitness") > -1) break
tobj = new RunFitParm("",0,0,0,0,0)
sscanf(tstr, "%*[^\"]\"%[^\"]\",%g,%g,%g,%g,%g", tobj.name, &tobj.val,\
&tobj.low, &tobj.high, &tobj.doarg, &tobj.uselog)
tobj.setname(tobj.name)
tobj.domain()
// sscanf(tstr, "%*[^\"]\"%[^\"]\",%g,%g,%g,%g", tobj.name, &tobj.val,\
// &tobj.low, &tobj.high, &tobj.doarg)
// tobj.setname(tobj.name)
// printf("%s |%s| %s", tobj, tobj.name, tstr)
declare(tobj)
tobj.play_one()
parmlist.append(tobj)
}
objref tobj
}
// this is probably not necessary because the Pointer will do it automatically
proc declare() { // function fitters often declare their own variables
if (sf.substr($o1.name, "$") == -1) {
if(!execute1($o1.name, 0)) {
sprint(tstr, "%s = %g", $o1.name, $o1.val)
execute1(tstr)
}
}
}
endtemplate ParmFitness
begintemplate ParmFitnessGui
public pf, map, unmap, dact, mulfit, run, c2p, p2c
public showopt, gmode, gensel
public mapsave, gengui, showargs, showdomain, usepanel
objref pf, sf, symch_, mulfit
external hoc_obj_, parmfitness_generator_list_
external mulfit_optimizers_, mulfit_optimizer_names_
strdef amodestr, gmodestr, tstr, tstr1
objref vbox, hbox, this, tobj, domainlist
public uselog, domainlist
objref parmbox, domainbox
objref gengui_, genguibox_
objref usepanelbox_
proc init() {
pf = $o1
mulfit = $o2
build()
sf = new StringFunctions()
}
proc run() {
pf.putall()
tobj = new Vector(50)
pf.doarg_get(tobj)
if (tobj.size) {
pf.efun(tobj.size, &tobj.x[0])
}else{
pf.efun(0)
}
}
proc runall() {local i
run()
for i=0, pf.generatorlist.count-1 {
if (!pf.generatorlist.object(i).use) {
pf.generatorlist.object(i).gen.efun()
}
}
}
proc build() {local i
vbox = new VBox(3)
vbox.save("")
vbox.dismiss_action("unmap()")
vbox.intercept(1)
xpanel(pf.title, 1)
xvarlabel(pf.title)
xpvalue("ErrorValue", &pf.errval, 0, "run()")
xpanel()
hbox = new HBox(3)
hbox.intercept(1)
tobj = new VBox(3)
tobj.intercept(1)
xpanel("", 1)
xmenu("Parameters")
xmenu("Select Optimizer")
for i= 0, mulfit_optimizers_.count - 1 {
sprint(tstr, "showopt(%d)", i)
xbutton(mulfit_optimizer_names_.object(i).s, tstr)
}
xmenu()
xbutton("Parameter Panel", "showargs()")
xbutton("Domain Panel", "showdomain()")
xbutton("Add Parameter", "addarg()")
xradiobutton("Remove Parameter", "amode=3 amodestr=\"Remove\"")
xradiobutton("Change Parameter", "amode=4 amodestr=\"Change\"")
xmenu("Parm import/export")
xbutton("Top level to Parm", "t2p()")
xbutton("Clipboard to Parm", "c2p()")
xbutton("Parm to Clipboard", "p2c()")
xmenu()
if (pf.pc.nhost > 0) {
xmenu("Parallel")
xbutton("Update context", "update_context()")
xbutton("Test context", "test_context()")
xmenu()
}
xmenu()
amode=1 amodestr=""
xvarlabel(amodestr)
xpanel()
pf.parmlist.browser("", "name")
pf.parmlist.accept_action("parmsel(hoc_ac_)")
tobj.intercept(0)
tobj.map()
tobj = new VBox(3)
tobj.intercept(1)
xpanel("", 1)
xmenu("Generators")
xmenu("Add Fitness Generator")
xbutton("Add Run Fitness", "addgen(0)")
xbutton("Add Function Fitness", "addgen(1)")
xbutton("Add Fitness Primitive", "addgen(2)")
xbutton("Add Multiple Run Fitter", "addgen(3)")
for i=4, parmfitness_generator_list_.count - 1 {
sprint(tstr, "addgen(%d)", i)
sprint(tstr1, "Add %s", parmfitness_generator_list_.object(i).s)
xbutton(tstr1, tstr)
}
xmenu()
xradiobutton("Display Generator", "gmode=1 gmodestr=\"Display\"")
xradiobutton("Use Generator", "gmode=2 gmodestr=\"Toggle\"")
xradiobutton("Remove Generator", "gmode=3 gmodestr=\"Remove\"")
xradiobutton("Change Name", "gmode=4 gmodestr=\"Change Name\"")
xradiobutton("Clone Generator", "gmode=5 gmodestr=\"Clone\"")
xbutton("Reorder upward", "reorder(-1)")
xbutton("Rorder downward", "reorder(1)")
xbutton("Multiple protocol name", "chtitle()")
xbutton("View all Graphs", "gview()")
xbutton("Pop up \"Use\" panel", "usepanel()")
xbutton("Run all", "runall()")
xmenu()
gmode = 1 gmodestr="Display"
xvarlabel(gmodestr)
xpanel()
pf.generatorlist.browser("", "s")
pf.generatorlist.select_action("gensel(hoc_ac_, 0)")
pf.generatorlist.accept_action("gensel(hoc_ac_, 1)")
tobj.intercept(0)
tobj.map()
hbox.intercept(0)
hbox.map()
vbox.intercept(0)
}
proc update_context() {
pf.save_context()
}
proc test_context() {local p
tobj = new Vector(50)
pf.doarg_get(tobj)
pf.pc.context(this, "partest_efun", tobj)
partest_efun(tobj)
}
proc partest_efun() {
tobj = $o1
if (tobj.size) {
pf.efun(tobj.size, &tobj.x[0])
}else{
pf.efun(0)
}
print pf.errval
}
proc showopt() {
sprint(tstr, "mulfit.opt = new %s(pf)", mulfit_optimizers_.object($1).s)
execute(tstr, this)
mulfit.showopt()
}
proc t2p() {local i
for i=0, pf.parmlist.count-1 {
tobj = pf.parmlist.object(i)
if (sf.head(tobj.name, "\\$", tstr) == -1) {
sprint(tstr, "%s.val = %s", tobj, tobj.name)
execute1(tstr)
}
}
}
proc p2c() {
hoc_obj_[0] = new Vector() pf.argget(hoc_obj_[0])
hoc_obj_[1] = new Vector(hoc_obj_[0].size)
hoc_obj_[1].indgen
}
proc c2p() {local i, n
n = pf.parmlist.count
if (n != hoc_obj_[0].size) {
print "clipboard not same size as parmlist"
sqrt(-1)
}
for i=0, n-1 {
pf.parmlist.object(i).val = hoc_obj_[0].x[i]
}
pf.putall()
}
proc gview() {local i, j
j = .2
for i=0, pf.generatorlist.count-1 {
tobj = pf.generatorlist.object(i)
// if (tobj.use) {
j = tobj.gen.gview(j, pf.title)
// }
}
}
proc usepanel() {local i
usepanelbox_ = new VBox()
usepanelbox_.save("")
usepanelbox_.intercept(1)
xpanel("")
for i=0, pf.generatorlist.count-1 {
tobj = pf.generatorlist.object(i)
sprint(tstr, "use_action(%d)", i)
xcheckbox(tobj.gen.title, &tobj.use, tstr)
}
xpanel()
usepanelbox_.intercept(0)
sprint(tstr, "%s use toggle", mulfit)
if (numarg() > 3) {
usepanelbox_.map(tstr, $1, $2, $3, $4)
}else{
usepanelbox_.map(tstr)
}
objref tobj
}
proc use_action() {local i
i = pf.generatorlist.selected
pf.generatorlist.select(-1)
tobj = pf.generatorlist.object($1)
tobj.use += 1
tobj.toggle()
pf.generatorlist.remove($1)
pf.generatorlist.insrt($1, tobj)
pf.generatorlist.select(i)
}
proc reorder() { local i //selected upward -1, downward 1
i = pf.generatorlist.selected
if (i != -1 && i + $1 > -1 && i + $1 < pf.generatorlist.count) {
dgen()
tobj = pf.generatorlist.object(i)
pf.generatorlist.select(-1)
pf.generatorlist.remove(i)
pf.generatorlist.insrt(i+$1, tobj)
pf.generatorlist.select(i+$1)
}
}
proc chtitle() {
tstr = pf.title
if (string_dialog("Multiple Run Protocol name", tstr)) {
pf.title = tstr
mulfit.title = pf.title
}
}
proc addgen() {
if ($1 >= 0 && $1 < parmfitness_generator_list_.count) {
sprint(tstr, "tobj = new %s(0)", parmfitness_generator_list_.object($1).s)
execute(tstr, this)
pf.generatorlist.append(new GenInfo(tobj))
if (object_id(gengui_) != 0) {
gengui_.intercept(1)
pf.generatorlist.object(pf.generatorlist.count-1).gen.map()
gengui_.intercept(0)
}
objref tobj
}
}
proc parmsel() {
if ($1 < 0) return
if (amode == 3) {
pf.parmlist.remove($1)
objref domainbox, domainlist, parmbox
}
if (amode == 4) {
tstr = pf.parmlist.object($1).name
if (string_dialog("Change parameter name", tstr)) {
tobj = pf.parmlist.object($1)
tobj.setname(tstr)
pf.parmlist.remove($1)
pf.parmlist.insrt($1, tobj)
objref tobj
objref domainbox, domainlist, parmbox
}
}
}
proc addarg() {
if (object_id(symch_) == 0) {
symch_ = new SymChooser("Fit Parameter")
}
if (symch_.run()) {
symch_.text(tstr)
tobj = new RunFitParm(tstr)
pf.declare(tobj)
pf.parmlist.append(tobj)
objref domainbox, domainlist, parmbox
if (sf.head(tstr, "\\$", tstr1) == -1) {
sprint(tstr, "%s.val = %s", tobj, tstr)
execute1(tstr)
}
}
}
proc gensel() {local i
i = $1
if (gmode == 1) { // display
gengui(i)
}
if ($2 == 0) return
if (gmode == 2) { // use toggle
tobj = pf.generatorlist.object(i)
tobj.toggle()
pf.generatorlist.remove(i)
pf.generatorlist.insrt(i, tobj)
pf.generatorlist.select(i)
}
if (gmode == 3) { // remove
tobj = pf.generatorlist.object(i)
pf.generatorlist.remove(i)
pf.generatorlist.select(-1)
objref tobj
dgen()
}
if (gmode == 4) { // change name
tobj = pf.generatorlist.object(i)
tstr = tobj.gen.title
if (string_dialog("Change generator title", tstr)) {
tobj.gen.chtitle(tstr)
tobj.toggle() tobj.toggle()
pf.generatorlist.remove(i)
pf.generatorlist.insrt(i,tobj)
pf.generatorlist.select(i)
dgen()
}
}
if (gmode == 5) { // clone
pf.generatorlist.object(i).gen.clone(tobj)
pf.generatorlist.insrt(i+1, new GenInfo(tobj))
dgen()
}
}
proc gengui() {local i
doNotify() // without this, mswin gives error when mulrunfit window not the top window
card_ = $1
if (object_id(gengui_) == 0) {
tobj = new VBox(3)
tobj.intercept(1)
tobj.save("")
// tobj.ref(this)
tobj.dismiss_action("dact()")
gengui_ = new Deck()
gengui_.intercept(1)
for i=0, pf.generatorlist.count-1 {
pf.generatorlist.object(i).gen.map()
}
gengui_.intercept(0)
gengui_.flip_to($1)
gengui_.map()
tobj.intercept(0)
sprint(tstr, "%s Generators", mulfit)
if (numarg() > 4) {
tobj.map(tstr, $2, $3, $4, $5)
}else{
tobj.map(tstr)
}
genguibox_ = tobj
}
gengui_.flip_to($1)
}
proc dgen() {
if (object_id(genguibox_) != 0) {
genguibox_.unmap
}
objref gengui_, usepanelbox_
}
proc dact() {
dgen()
objref parmbox, domainbox, domainlist
}
proc mapsave() {
if (object_id(genguibox_)) if (genguibox_.ismapped) {
$o2.resize(4)
genguibox_.size(&$o2.x[0])
sprint(tstr, "{p.gengui(%d, %g, %g, %g, %g)}", card_, $o2.x[0], $o2.x[1], $o2.x[2], $o2.x[3])
$o1.save(tstr)
}
if (object_id(parmbox)) if (parmbox.ismapped) {
parmbox.size(&$o2.x[0])
sprint(tstr, "{p.showargs(%g, %g, %g, %g)}", $o2.x[0], $o2.x[1], $o2.x[2], $o2.x[3])
$o1.save(tstr)
}
if (object_id(domainbox)) if (domainbox.ismapped) {
domainbox.size(&$o2.x[0])
sprint(tstr, "{p.showdomain(%g, %g, %g, %g)}", $o2.x[0], $o2.x[1], $o2.x[2], $o2.x[3])
$o1.save(tstr)
}
if (object_id(usepanelbox_)) if (usepanelbox_.ismapped) {
usepanelbox_.size(&$o2.x[0])
sprint(tstr, "{p.usepanel(%g, %g, %g, %g)}", $o2.x[0], $o2.x[1], $o2.x[2], $o2.x[3])
$o1.save(tstr)
}
}
proc map() {
sprint(tstr, "%s", mulfit)
vbox.map(tstr)
}
proc unmap() {
if (object_id(genguibox_) != 0) {
genguibox_.unmap
}
vbox.unmap
}
proc showargs() {local n
n = pf.parmlist.count
if (n > 5) { //scrollbox
parmbox = new VBox(3,1)
}else{
parmbox = new VBox()
}
parmbox.save("")
parmbox.intercept(1)
for i=0, n-1 {
tobj = pf.parmlist.object(i)
xpanel("ParmValues", 1)
xcheckbox("", &tobj.doarg)
tstr = tobj.name
sprint(tstr1, "pf.parmlist.object(%d).play_one()", i)
xpvalue(tobj.name, &tobj.val, 1, tstr1)
xpanel()
}
parmbox.intercept(0)
parmbox.save("")
sprint(tstr, "%s parameters", mulfit)
if (numarg() > 3) {
parmbox.map(tstr, $1, $2, $3, $4)
}else{
parmbox.map(tstr)
}
objref tobj
}
proc chdomain() {
tobj = domainlist.object($1)
sprint(tstr1, "Enter: 0 low high or 1 low high for %s", tobj.name)
sprint(tstr, "%d %g %g", tobj.uselog, tobj.low, tobj.high)
while (string_dialog(tstr1, tstr)) {
if (sscanf(tstr, "%g %g %g", &x1, &x2, &x3) == 3) {
tobj.uselog = (x1 != 0)
tobj.low = x2
tobj.high = x3
tobj.domain()
domainlist.remove($1)
domainlist.insrt($1, tobj)
objref tobj
break
}else{
sprint(tstr, "%d %g %g", tobj.uselog, tobj.low, tobj.high)
continue_dialog(\
"Must enter three space separated items, e.g. \"0 1e-6 1e6\" or \"1 1e-6 1e6\"")
}
}
}
proc uselog() {local i
domainlist.remove_all
for i=0, pf.parmlist.count-1 {
tobj = pf.parmlist.object(i)
tobj.uselog = $1
tobj.domain()
domainlist.append(tobj)
}
objref tobj
}
proc limits() {
domainlist.remove_all
for i=0, pf.parmlist.count-1 {
tobj = pf.parmlist.object(i)
tobj.low = $1
tobj.high = $2
tobj.domain()
domainlist.append(tobj)
}
objref tobj
}
proc showdomain() {local n
x1 = x2 = x3 = 0
n = pf.parmlist.count
domainlist = new List()
for i=0, n-1 {
domainlist.append(pf.parmlist.object(i))
}
domainbox = new VBox()
domainbox.save("")
domainbox.intercept(1)
xpanel("")
xmenu("group attributes")
xbutton("use log scale", "uselog(1)")
xbutton("use linear scale", "uselog(0)")
xbutton("positive definite limits", "limits(1e-9,1e9)")
xbutton("unbounded limits", "limits(-1e6,1e6)")
xmenu()
xlabel("Log low high name ")
xpanel()
domainlist.browser("", "domain_")
domainlist.accept_action("chdomain(hoc_ac_)")
domainbox.intercept(0)
domainbox.save("")
sprint(tstr, "%s Domain", mulfit)
if (numarg() > 3) {
domainbox.map(tstr, $1, $2, $3, $4)
}else{
domainbox.map(tstr)
}
objref tobj
}
endtemplate ParmFitnessGui