diff --git a/mc_work/dorun.go b/mc_work/dorun.go
index 4c05d432cf70364087dfffaf086c65fa3aff183f..3a2d7ce6d35a4e21f1a3a546cad17d41d508aa83 100644
--- a/mc_work/dorun.go
+++ b/mc_work/dorun.go
@@ -159,7 +159,7 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float64) {
// printfVal is the loop to print out the function value and coordinates
// probably for later plotting.
-func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float64) {
+func printfVal(fOut io.Writer, x []float32, n int, tmprtr float64, fOld float64) {
fmt.Fprintf(fOut, "%d,%.4g,%.5g", n, tmprtr, fOld)
for _, xx := range x {
fmt.Fprintf(fOut, ",%.2g", xx)
@@ -169,7 +169,7 @@ func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float
// saveStep is called when we accept a change. It writes or saves for
// later plotting.
-func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64) {
+func saveStep(cprm *cprm, n int, tmprtr float64, x []float32, fTrial float64) {
cprm.plotnstp = append(cprm.plotnstp, float64(n)) // num steps
if cprm.fplotWrt != nil { // Function values // function values
cprm.plotf = append(cprm.plotf, fTrial)
@@ -184,7 +184,7 @@ func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64)
}
// nRunAdj will try to adjust the step size, given our history of accept/reject.
-func nRunAdj(mcPrm *McPrm, nstep uint32, runAcc float64, xDlta float64) float64 {
+func nRunAdj(mcPrm *McPrm, nstep int, runAcc float64, xDlta float64) float64 {
const step = "step"
if runAcc < accRateIdeal-0.01 { // acceptance rate too low
xDlta *= 0.9
@@ -236,7 +236,7 @@ func DoRun(mcPrm *McPrm) ([]byte, []byte, error) {
xDlta := mcPrm.XDlta // Adaptable step size
saveStep(&cprm, 0, tmprtr, x, fOld)
- for n := uint32(0); n < mcPrm.NStep; n++ {
+ for n := 0; n < mcPrm.NStep; n++ {
var accept bool
nRunAcc--
if nRunAcc == 0 { // Do we want to try adjusting the step size ?
diff --git a/mc_work/mc_work.go b/mc_work/mc_work.go
index 476888ad621ab142bc8f2448cf2cd2ecb50cd47b..b3ad67f630bc5792f98bfa5c348c30119675c86a 100644
--- a/mc_work/mc_work.go
+++ b/mc_work/mc_work.go
@@ -13,8 +13,8 @@ type McPrm struct {
IniTmp, FnlTmp float64 // Initial and final temperatures
XIni []float32 // initial x slice
XDlta float64 // change x by up to +- xDlta in trial moves
- NStep uint32 // number of steps
- NRun uint32 // number of separate runs
+ NStep int // number of steps
+ NRun int // number of separate runs
fOutName string // where we write output to
fPltName string // where we plot to (function values)
xPltName string // where we plot x trajectories to
diff --git a/mc_work/rdprm.go b/mc_work/rdprm.go
index e3b8ad2619f65ad3b1ca6c477a713233d07660f8..c972a11a8841ab2bc1996f858d6e020281411040 100644
--- a/mc_work/rdprm.go
+++ b/mc_work/rdprm.go
@@ -36,14 +36,6 @@ var cmdDflt = []struct {
// digest digests the map, fills out our structure and sets the seed.
func digest(prmMap map[string]string, mcPrm *McPrm) error {
var err error
-/* getf := func(s string) float32 {
- if err != nil {
- return 0.0
- }
- var r float64
- r, err = strconv.ParseFloat(s, 32)
- return float32(r)
- } */
getf64 := func(s string) float64 {
if err != nil {
return 0.0
@@ -52,13 +44,13 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error {
r, err = strconv.ParseFloat(s, 64)
return r
}
- getu := func(s string) uint32 {
+ geti := func(s string) int {
if err != nil {
return 0
}
- var u uint64
- u, err = strconv.ParseUint(s, 10, 32)
- return uint32(u)
+ var u int64
+ u, err = strconv.ParseInt(s, 10, 32)
+ return int(u)
}
getx := func(s string) []float32 {
if err != nil {
@@ -83,13 +75,13 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error {
mcPrm.IniTmp = getf64(prmMap["ini_temp"])
mcPrm.FnlTmp = getf64(prmMap["final_temp"])
mcPrm.XDlta = getf64(prmMap["x_delta"])
- mcPrm.NStep = getu(prmMap["n_step"])
- mcPrm.NRun = getu(prmMap["n_run"])
+ mcPrm.NStep = geti(prmMap["n_step"])
+ mcPrm.NRun = geti(prmMap["n_run"])
mcPrm.XIni = getx(prmMap["x_ini"])
mcPrm.fOutName = prmMap["foutname"]
mcPrm.fPltName = prmMap["fpltname"]
mcPrm.xPltName = prmMap["xpltname"]
- seed = int64(getu(prmMap["seed"]))
+ seed = int64(geti(prmMap["seed"]))
if err != nil { // Only returns the first error encountered
return err
}
diff --git a/mc_work/realmain_nogfx.go b/mc_work/realmain_nogfx.go
index a63116ed07f5df35dcda0a070bc6a990b4cc9462..8551c4308c834f658b940dd768c570aa3ba28322 100644
--- a/mc_work/realmain_nogfx.go
+++ b/mc_work/realmain_nogfx.go
@@ -20,7 +20,7 @@ func realmain(fp io.Reader) error {
if err := RdPrm(fp, &mcPrm); err != nil {
return err
}
- if _, _, err := doRun(&mcPrm); err != nil {
+ if _, _, err := DoRun(&mcPrm); err != nil {
return err
}
diff --git a/ui/output_tab.go b/ui/output_tab.go
index f8dbdc7b6c8bd58976db421ecd5237390eeb35e6..41a44f4266d748696d362be8c96ef6563433b960 100644
--- a/ui/output_tab.go
+++ b/ui/output_tab.go
@@ -30,35 +30,44 @@ type workstatus struct {
status status
}
+// showIniTab is just a card to be shown before we have any calculations
+// done.
func showIniTab(cntr *fyne.Container) {
cntr.Add(widget.NewCard("No results yet", "go back to the input", nil))
}
-func showCalcTab(cntr *fyne.Container) {
- for _, c := range cntr.Objects {
- cntr.Remove(c)
+// emptyContainer gets rid of any old contents
+func emptyContainer (cntr *fyne.Container) {
+ for _, o := range cntr.Objects {
+ cntr.Remove(o)
}
+}
+
+// showCalcTab is shown while calculating. Have to check if the refresh()
+// is actually necessary.
+func showCalcTab(cntr *fyne.Container) {
+ emptyContainer (cntr)
cntr.Add(widget.NewCard("calculating", "busy", nil))
cntr.Refresh()
}
// showResultsTab show the two plots
-
func showResultsTab(cntr *fyne.Container, fdata, xdata []byte) {
- for _, c := range cntr.Objects {
- cntr.Remove(c)
- }
+ emptyContainer (cntr)
+ pictureSize := fyne.Size{Width: 500, Height: 250}
fImage := canvas.NewImageFromReader(bytes.NewReader(fdata), "func.png")
fImage.FillMode = canvas.ImageFillContain
- fImage.SetMinSize( fyne.Size{500, 300})
+ fImage.SetMinSize( pictureSize)
xImage := canvas.NewImageFromReader(bytes.NewReader(xdata), "xdata.png")
xImage.FillMode = canvas.ImageFillContain
- xImage.SetMinSize( fyne.Size{500, 300})
+ xImage.SetMinSize( pictureSize)
content := container.NewGridWithRows(2, fImage, xImage)
cntr.Add(content)
-
}
+// outputTab is run as a background process. After showing the initial
+// screen, it sits and waits on notifications. When it gets one,
+// it redraws its tab.
func outputTab(chn chan workstatus, cntr *fyne.Container) {
showIniTab(cntr)
for s := range chn {
diff --git a/ui/param_tab.go b/ui/param_tab.go
index 504f283e494762ea16f6cfb3bbff1da48b83cf16..c38f127ee914c9df41ec51990c9d2d25d104e95b 100644
--- a/ui/param_tab.go
+++ b/ui/param_tab.go
@@ -50,17 +50,19 @@ func s2f32(s string) ([]float32, error) {
return x, nil
}
+// validateXini checks if we can convert a string to a slice of float32's.
+// Unfortunately, fyne calls this function every time the cursor is moved
+// in the field. I think this is a little bug on their part.
func validateXini(s string) error {
- fmt.Println("validation called")
_, err := s2f32(s)
return err
}
-// paramScreen sets up a screen full of parameters we can adjust. It returns a the screen
-// and a function to be called to refresh it if parameters are changed elsewhere, like
-// reading from a file.
+// paramScreen sets up a screen full of parameters we can adjust.
+// It returns the screen and a function to be called to refresh it.
+// This is necessary, since there is a button to read parameters from
+// a file, which means all the values should be updated.
func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) {
-
iniTmp := binding.BindFloat(&mcPrm.IniTmp)
iniTmpEntry := widget.NewEntryWithData(binding.FloatToString(iniTmp))
iniTmpLabel := widget.NewLabel("initial temp")
@@ -87,21 +89,30 @@ func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) {
xIniEntry.Validator = validateXini
xIniLabel := widget.NewLabel("X ini")
+ nStepBnd := binding.BindInt(&mcPrm.NStep)
+ nStepEntry := widget.NewEntryWithData(binding.IntToString(nStepBnd))
+ nStepLabel := widget.NewLabel("num steps")
+
r := container.NewGridWithColumns(2,
iniTmpLabel, iniTmpEntry,
fnlTmpLabel, fnlTmpEntry,
xDltaLabel, xDltaEntry,
- xIniLabel, xIniEntry)
+ xIniLabel, xIniEntry,
+ nStepEntry, nStepLabel)
refreshPScreen := func() {
iniTmp.Reload()
fnlTmp.Reload()
xDlta.Reload()
xIniEntry.SetText(fslicestrng(mcPrm.XIni))
+ nStepBnd.Reload()
}
return r, refreshPScreen
}
-func checkok(c *fyne.Container, parent fyne.Window) error {
+
+// checkOk does a last pass over all fields and calls any validators
+// it can find. A run can only be started if everything seems to be OK.
+func checkOk(c *fyne.Container, parent fyne.Window) error {
for _, obj := range c.Objects {
if ent, ok := obj.(*widget.Entry); ok {
if err := ent.Validate(); err != nil {
@@ -133,7 +144,7 @@ func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, refreshme func()) error {
} else {
fmt.Println("I think mcprm is", mcPrm)
refreshme()
- dialog.NewInformation("OK confirmed", "read file, no errors", parent).Show()
+ dialog.NewInformation("OK", "read file, no errors", parent).Show()
return
}
}
@@ -160,11 +171,10 @@ func inputTab(mcPrm *mcwork.McPrm, parent fyne.Window, chn chan workstatus) (*fy
}
}
startrun := func() {
- if err := checkok(paramBinding, parent); err != nil {
+ if err := checkOk(paramBinding, parent); err != nil {
dialog.NewError(err, parent).Show()
return
}
- fmt.Println("I want to run with paremeters", mcPrm)
chn <- workstatus{status: calculating}
if fdata, xdata, err := mcwork.DoRun(mcPrm); err != nil {
dialog.NewError(err, parent).Show()