From 27c8e3bb8a4e20db314b9a47a1e9993b6687babd Mon Sep 17 00:00:00 2001
From: "Andrew E. Torda" <torda@zbh.uni-hamburg.de>
Date: Thu, 17 Feb 2022 20:49:09 +0100
Subject: [PATCH] First version which runs and puts results in a new window.
Still to be done - things like putting the rest of the parameters into the
input tab.
---
Makefile | 4 +
go.sum | 22 +---
main_gfx.go | 30 +++++
main.go => main_nogfx.go | 3 +-
mc_work/dorun.go | 89 +++++++--------
mc_work/export_test.go | 2 +-
mc_work/mc_work.go | 54 ++-------
mc_work/mc_work_test.go | 3 +-
mc_work/plot.go | 2 +-
mc_work/rdprm.go | 30 +++--
mc_work/realmain_nogfx.go | 48 ++++++++
mc_work/set_suffix.go | 2 +-
mc_work/unwanted.goat | 16 ---
ui/embed_exmple.go | 20 ++++
example_input => ui/example_input | 0
ui/mymain.go | 45 ++++++++
ui/param_tab.go | 182 ++++++++++++++++++++++++++++++
ui/scrnplt.go | 18 +--
ui/scrnplt.goat | 32 ------
ui/ui_run.go | 43 +++++++
20 files changed, 457 insertions(+), 188 deletions(-)
create mode 100644 main_gfx.go
rename main.go => main_nogfx.go (87%)
create mode 100644 mc_work/realmain_nogfx.go
delete mode 100644 mc_work/unwanted.goat
create mode 100644 ui/embed_exmple.go
rename example_input => ui/example_input (100%)
create mode 100644 ui/mymain.go
create mode 100644 ui/param_tab.go
delete mode 100644 ui/scrnplt.goat
create mode 100644 ui/ui_run.go
diff --git a/Makefile b/Makefile
index 923682c..6268a46 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,10 @@
all:
go build ./...
+test:
+ go test ./...
+ go test -tags no_gfx ./...
+
clean:
go clean
rm -rf */*_delme.*
diff --git a/go.sum b/go.sum
index 95dec1b..a90edb9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,3 @@
-fyne.io/fyne v1.4.3 h1:356CnXCiYrrfaLGsB7qLK3c6ktzyh8WR05v/2RBu51I=
-fyne.io/fyne v1.4.3/go.mod h1:8kiPBNSDmuplxs9WnKCkaWYqbcXFy0DeAzwa6PBO9Z8=
fyne.io/fyne/v2 v2.1.2 h1:avp9CvLAUdvE7fDMtH1tVKyjxEWHWcpow6aI6L7Kvvw=
fyne.io/fyne/v2 v2.1.2/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -14,15 +12,11 @@ github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fyne-io/mobile v0.1.2/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY=
-github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f h1:s0O46d8fPwk9kU4k1jj76wBquMVETx7uveQD9MCIQoU=
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
-github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=
@@ -32,10 +26,11 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng=
github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -56,7 +51,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E=
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
@@ -64,27 +58,20 @@ gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20220120103412-d663ebb46145 h1:
gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20220120103412-d663ebb46145/go.mod h1:5CNHyqeidRypmIVTnQksGqnmP56Oshw1Zv1nlUezrpQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -92,19 +79,16 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200328031815-3db5fc6bac03/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/main_gfx.go b/main_gfx.go
new file mode 100644
index 0000000..db7a65b
--- /dev/null
+++ b/main_gfx.go
@@ -0,0 +1,30 @@
+// Aug 2021
+// +build !no_gfx
+
+// Ackley_mc is for playing with Monte Carlo or simulated annealing on the
+// ackley function in N dimensions.
+//
+// ackley_mc input_file
+// where input_file has a list of keywords and values.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "example.com/ackley_mc/ui"
+)
+
+const (
+ exitSuccess = iota
+ exitFailure
+)
+
+func main() {
+ if err := ui.MyMain(); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(exitFailure)
+ }
+ os.Exit(exitSuccess)
+}
diff --git a/main.go b/main_nogfx.go
similarity index 87%
rename from main.go
rename to main_nogfx.go
index e69a7cb..adae628 100644
--- a/main.go
+++ b/main_nogfx.go
@@ -1,4 +1,5 @@
// Aug 2021
+// +build no_gfx
// Ackley_mc is for playing with Monte Carlo or simulated annealing on the
// ackley function in N dimensions.
@@ -21,7 +22,7 @@ const (
)
func main() {
- if err := mc_work.MyMain(); err != nil {
+ if err := mcwork.MyMain(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(exitFailure)
}
diff --git a/mc_work/dorun.go b/mc_work/dorun.go
index 78c0552..4c05d43 100644
--- a/mc_work/dorun.go
+++ b/mc_work/dorun.go
@@ -1,5 +1,5 @@
// Aug 2021
-package mc_work
+package mcwork
import (
"bufio"
@@ -12,7 +12,6 @@ import (
"sync"
"example.com/ackley_mc/ackley"
- "example.com/ackley_mc/ui"
)
const (
@@ -54,35 +53,35 @@ type cprm struct { // parameters calculated from input
}
// isNotSane checks for obviously silly parameters
-func isNotSane(mcPrm *mcPrm) error {
+func isNotSane(mcPrm *McPrm) error {
if mcPrm.fOutName == "" && mcPrm.fPltName == "" && mcPrm.xPltName == "" {
if false { // if there are no graphics compiled in, ..
return fmt.Errorf("All output files are empty. You would not see anything")
}
}
- if mcPrm.iniTmp < 0 {
- return fmt.Errorf("negative initial temperature %g", mcPrm.iniTmp)
+ if mcPrm.IniTmp < 0 {
+ return fmt.Errorf("negative initial temperature %g", mcPrm.IniTmp)
}
return nil
}
// setupRun does things like get the cooling rate, seed the random numbers.
-func setupRun(mcPrm *mcPrm, cprm *cprm) error {
+func setupRun(mcPrm *McPrm, cprm *cprm) error {
var err error
if mcPrm.dummy {
return nil
}
cprm.rand = rand.New(rand.NewSource(getSeed()))
- if mcPrm.iniTmp != mcPrm.fnlTmp { // cooling or constant temperature ?
+ if mcPrm.IniTmp != mcPrm.FnlTmp { // cooling or constant temperature ?
var coolrate float64
cprm.coolme = true
- if mcPrm.fnlTmp > mcPrm.iniTmp {
+ if mcPrm.FnlTmp > mcPrm.IniTmp {
const finalTempErr = "Final temp %g higher than initial temp %g"
- return fmt.Errorf(finalTempErr, mcPrm.fnlTmp, mcPrm.iniTmp)
+ return fmt.Errorf(finalTempErr, mcPrm.FnlTmp, mcPrm.IniTmp)
}
- nStep := float64(mcPrm.nStep)
- fnlTmp, iniTmp := float64(mcPrm.fnlTmp), float64(mcPrm.iniTmp)
+ nStep := float64(mcPrm.NStep)
+ fnlTmp, iniTmp := float64(mcPrm.FnlTmp), float64(mcPrm.IniTmp)
if fnlTmp == 0 { // avoid divide by zeroes
fnlTmp = math.SmallestNonzeroFloat32
}
@@ -112,7 +111,7 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
var w bytes.Buffer // could be fancy, preallocate and use bytes.Newbuffer
cprm.fplotWrt = &w
}
- n_alloc := mcPrm.nStep / 5 // About a fifth of the number of steps
+ n_alloc := mcPrm.NStep / 5 // About a fifth of the number of steps
cprm.plotnstp = make([]float64, 0, n_alloc)
cprm.plotf = make([]float64, 0, n_alloc)
if cprm.coolme {
@@ -130,7 +129,7 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
var w bytes.Buffer
cprm.xplotWrt = &w // I think we can remove the preceding line
}
- cprm.plotXtrj = make([]float32, 0, int(n_alloc)*len(mcPrm.xIni))
+ cprm.plotXtrj = make([]float32, 0, int(n_alloc)*len(mcPrm.XIni))
if err = isNotSane(mcPrm); err != nil {
return err
}
@@ -148,14 +147,14 @@ func alt_newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) {
}
// newx will move just one coordinate at a time
-func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) {
+func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float64) {
var iDim int
if (len(xold)) > 1 {
iDim = rand.Intn(len(xold)) // pick one dimension to change
}
- t := 2.*rand.Float32() - 1
+ t := 2.*rand.Float64() - 1
t *= xDlta
- xT[iDim] = xold[iDim] + t
+ xT[iDim] = xold[iDim] + float32(t)
}
// printfVal is the loop to print out the function value and coordinates
@@ -185,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 float32) float32 {
+func nRunAdj(mcPrm *McPrm, nstep uint32, runAcc float64, xDlta float64) float64 {
const step = "step"
if runAcc < accRateIdeal-0.01 { // acceptance rate too low
xDlta *= 0.9
@@ -205,10 +204,10 @@ func nRunAdj(mcPrm *mcPrm, nstep uint32, runAcc float64, xDlta float32) float32
// coordinates and function, we use double precision for the temperature.
// Unfortunately, the plotting functions want double precision, so we store
// an awful lot of stuff as float64.
-func doRun(mcPrm *mcPrm) error {
+func DoRun(mcPrm *McPrm) ([]byte, []byte, error) {
var cprm cprm
if err := setupRun(mcPrm, &cprm); err != nil {
- return err
+ return nil, nil, err
}
if cprm.doTxtFval { // The text file documenting the run
defer cprm.fOutRaw.Close()
@@ -220,19 +219,24 @@ func doRun(mcPrm *mcPrm) error {
}
var nAcc int // Counter, number of accepted moves
- x := make([]float32, len(mcPrm.xIni)) // current position
- xT := make([]float32, len(mcPrm.xIni)) // trial position
+ x := make([]float32, len(mcPrm.XIni)) // current position
+ xT := make([]float32, len(mcPrm.XIni)) // trial position
runAcc := accRateIdeal // Running acceptance rate, exponentially weighted
- copy(x, mcPrm.xIni)
+
+ for i := range mcPrm.XIni {
+ x[i] = float32(mcPrm.XIni[i])
+ }
+
+ // copy(x, mcPrm.XIni) I had to replace this with the loop above
fOld := ackley.Ackley(x) // Initial function value
fTrial := fOld
- tmprtr := float64(mcPrm.iniTmp)
+ tmprtr := float64(mcPrm.IniTmp)
nRunAcc := nRunAccAdj // Every nRunAccAdj, try adjusting the step size.
const runMult = 0.99
- xDlta := mcPrm.xDlta // Adaptable step size
+ xDlta := mcPrm.XDlta // Adaptable step size
saveStep(&cprm, 0, tmprtr, x, fOld)
- for n := uint32(0); n < mcPrm.nStep; n++ {
+ for n := uint32(0); n < mcPrm.NStep; n++ {
var accept bool
nRunAcc--
if nRunAcc == 0 { // Do we want to try adjusting the step size ?
@@ -266,32 +270,25 @@ func doRun(mcPrm *mcPrm) error {
// On plots, we want the last step, even if nothing changed.
if fTrial != fOld { // last move was not accepted, so we have to add last step
- saveStep(&cprm, mcPrm.nStep, tmprtr, x, fOld)
+ saveStep(&cprm, mcPrm.NStep, tmprtr, x, fOld)
}
- defer fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1)
+ defer fmt.Println("n accepted:", nAcc, "of", mcPrm.NStep+1)
if err := plotfWrt(&cprm); err != nil {
- return err
+ return nil, nil, err
}
- if err := plotxWrt(&cprm, len(mcPrm.xIni)); err != nil {
- return err
- }
- {
- var fdata, xdata []byte
- if funcBuf, ok := cprm.fplotWrt.(withBytes); ok {
- fdata = funcBuf.Bytes()
- }
- if xBuf, ok := cprm.xplotWrt.(withBytes); ok {
- xdata = xBuf.Bytes()
- }
- nothing(fdata, xdata)
- ui.Scrnplt(fdata, xdata)
- nothing(ui.Scrnplt)
+ if err := plotxWrt(&cprm, len(mcPrm.XIni)); err != nil {
+ return nil, nil, err
}
- /* if bBuf, := plotxWrt(&cprm, mcPrm.xPltName, len(mcPrm.xIni)); err != nil {
- return err
- } */
+ var fdata, xdata []byte
+ if funcBuf, ok := cprm.fplotWrt.(withBytes); ok {
+ fdata = funcBuf.Bytes()
+ }
+ if xBuf, ok := cprm.xplotWrt.(withBytes); ok {
+ xdata = xBuf.Bytes()
+ }
+ nothing(fdata, xdata)
- return nil
+ return fdata, xdata, nil
}
diff --git a/mc_work/export_test.go b/mc_work/export_test.go
index 2d4bddf..f8d7102 100644
--- a/mc_work/export_test.go
+++ b/mc_work/export_test.go
@@ -1,4 +1,4 @@
-package mc_work
+package mcwork
var SetSuffix = setSuffix
var RemoveQuotes = removeQuotes
diff --git a/mc_work/mc_work.go b/mc_work/mc_work.go
index 7b65f85..476888a 100644
--- a/mc_work/mc_work.go
+++ b/mc_work/mc_work.go
@@ -1,22 +1,20 @@
// Aug 2021
-package mc_work
+package mcwork
import (
"flag"
"fmt"
- "io"
"os"
-
- "example.com/ackley_mc/ackley"
)
-type mcPrm struct {
- iniTmp, fnlTmp float32 // Initial and final temperatures
- xIni []float32 // initial x slice
- xDlta float32 // change x by up to +- xDlta in trial moves
- nStep uint32 // number of steps
- nRun uint32 // number of separate runs
+// Have to export everything so the graphical interface can get to them
+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
fOutName string // where we write output to
fPltName string // where we plot to (function values)
xPltName string // where we plot x trajectories to
@@ -31,39 +29,3 @@ func usage() {
u := `[options] input_parameter_file`
fmt.Fprintf(flag.CommandLine.Output(), "usage of %s: %s\n", os.Args[0], u)
}
-
-// realmain is the real main function. The program wants to read from a file,
-// but we can have it read from an io.Reader and then use the test functions
-// for playing with it.
-func realmain(fp io.Reader) error {
- var mcPrm mcPrm
- if err := rdPrm(fp, &mcPrm); err != nil {
- return err
- }
- if err := doRun(&mcPrm); err != nil {
- return err
- }
- var x [1]float32
- ackley.Ackley(x[:])
- return nil
-}
-
-// MyMain is called from the real main. It opens the input file, but passes a
-// reader to the function that does the work. This lets us call it from a test
-// function.
-func MyMain() error {
- if len(os.Args) < 2 {
- usage()
- return fmt.Errorf("No input file given")
- }
- fname := os.Args[1]
- if fp, err := os.Open(fname); err != nil {
- return err
- } else {
- defer fp.Close()
- if err := realmain(fp); err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/mc_work/mc_work_test.go b/mc_work/mc_work_test.go
index 485c923..0a067f9 100644
--- a/mc_work/mc_work_test.go
+++ b/mc_work/mc_work_test.go
@@ -1,6 +1,7 @@
// Aug 2021
+// +build no_gfx
-package mc_work
+package mcwork
import (
"fmt"
diff --git a/mc_work/plot.go b/mc_work/plot.go
index e826884..e211260 100644
--- a/mc_work/plot.go
+++ b/mc_work/plot.go
@@ -15,7 +15,7 @@
// the X-axis differently. The solution is that we draw the temperature on both
// plots, but set all the style attributes to be invisible when we plot the
// X trajectories.
-package mc_work
+package mcwork
import (
"fmt"
diff --git a/mc_work/rdprm.go b/mc_work/rdprm.go
index 3730db7..e3b8ad2 100644
--- a/mc_work/rdprm.go
+++ b/mc_work/rdprm.go
@@ -4,7 +4,7 @@
// These are stored in a map along with string values. These are then converted
// to floats or ints and put into a structure or variable.
-package mc_work
+package mcwork
import (
"bufio"
@@ -34,15 +34,23 @@ var cmdDflt = []struct {
}
// digest digests the map, fills out our structure and sets the seed.
-func digest(prmMap map[string]string, mcPrm *mcPrm) error {
+func digest(prmMap map[string]string, mcPrm *McPrm) error {
var err error
- getf := func(s string) float32 {
+/* 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
+ }
+ var r float64
+ r, err = strconv.ParseFloat(s, 64)
+ return r
}
getu := func(s string) uint32 {
if err != nil {
@@ -72,12 +80,12 @@ func digest(prmMap map[string]string, mcPrm *mcPrm) error {
}
return x
}
- mcPrm.iniTmp = getf(prmMap["ini_temp"])
- mcPrm.fnlTmp = getf(prmMap["final_temp"])
- mcPrm.xDlta = getf(prmMap["x_delta"])
- mcPrm.nStep = getu(prmMap["n_step"])
- mcPrm.nRun = getu(prmMap["n_run"])
- mcPrm.xIni = getx(prmMap["x_ini"])
+ 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.XIni = getx(prmMap["x_ini"])
mcPrm.fOutName = prmMap["foutname"]
mcPrm.fPltName = prmMap["fpltname"]
mcPrm.xPltName = prmMap["xpltname"]
@@ -106,8 +114,8 @@ pairs. Values for x_ini are separated by commas without spaces.
return s
}
-// rdPrmInner is in a function by itself, to make testing easier
-func rdPrm(fp io.Reader, mcPrm *mcPrm) error {
+// RdPrm reads parameters from a io reader and fills out an control structure.
+func RdPrm(fp io.Reader, mcPrm *McPrm) error {
prmMap := make(map[string]string)
for _, s := range cmdDflt {
prmMap[s.key] = s.v // Put default values into map
diff --git a/mc_work/realmain_nogfx.go b/mc_work/realmain_nogfx.go
new file mode 100644
index 0000000..a63116e
--- /dev/null
+++ b/mc_work/realmain_nogfx.go
@@ -0,0 +1,48 @@
+// feb 2022
+// We are building a version without graphics
+// +build no_gfx
+
+
+// This should mirror the file realmain_gfx.go. It should also remain short.
+package mcwork
+
+import (
+ "io"
+ "os"
+ "fmt"
+)
+
+// realmain is the real main function. The program wants to read from a file,
+// but we can have it read from an io.Reader and then use the test functions
+// for playing with it.
+func realmain(fp io.Reader) error {
+ var mcPrm McPrm
+ if err := RdPrm(fp, &mcPrm); err != nil {
+ return err
+ }
+ if _, _, err := doRun(&mcPrm); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// MyMain is called from the real main. It opens the input file, but passes a
+// reader to the function that does the work. This lets us call it from a test
+// function.
+func MyMain() error {
+ if len(os.Args) < 2 {
+ usage()
+ return fmt.Errorf("No input file given")
+ }
+ fname := os.Args[1]
+ if fp, err := os.Open(fname); err != nil {
+ return err
+ } else {
+ defer fp.Close()
+ if err := realmain(fp); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/mc_work/set_suffix.go b/mc_work/set_suffix.go
index c0bf8d0..5428c20 100644
--- a/mc_work/set_suffix.go
+++ b/mc_work/set_suffix.go
@@ -1,5 +1,5 @@
// a utility
-package mc_work
+package mcwork
import (
"errors"
diff --git a/mc_work/unwanted.goat b/mc_work/unwanted.goat
deleted file mode 100644
index cf16011..0000000
--- a/mc_work/unwanted.goat
+++ /dev/null
@@ -1,16 +0,0 @@
-// maketicks this version works, but usually leaves you wanting one tick more.
-/*func alt_maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick {
- xmin, xmax, delta, prcsn := axisDscrpt.Xmin, axisDscrpt.Xmax, axisDscrpt.Delta, axisDscrpt.Prcsn
- var t []chart.Tick
- const fstr = "%.*f"
- xv, xl := xmin, fmt.Sprintf(fstr, prcsn, xmin)
- if xmin > 3.56 && xmin < 3.58 {
- fmt.Println (axisDscrpt)
- }
- for ; xv <= xmax; xv, xl = xv+delta, fmt.Sprintf("%.*f", prcsn, xv) {
- t = append(t, chart.Tick {Value: xv, Label: xl})
- }
-
- return t
-}*/
-
diff --git a/ui/embed_exmple.go b/ui/embed_exmple.go
new file mode 100644
index 0000000..44342ac
--- /dev/null
+++ b/ui/embed_exmple.go
@@ -0,0 +1,20 @@
+// 15 Feb 2022
+// Let us read up an example input file and put its contents into a McPrm
+// (monte carlo control parameters) structure.
+
+package ui
+
+import (
+ _ "embed"
+ "strings"
+
+ "example.com/ackley_mc/mc_work"
+)
+
+//go:embed example_input
+var exmplInput string
+
+func getExmpl(mcPrm *mcwork.McPrm) error {
+ s := strings.NewReader(exmplInput)
+ return mcwork.RdPrm(s, mcPrm)
+}
diff --git a/example_input b/ui/example_input
similarity index 100%
rename from example_input
rename to ui/example_input
diff --git a/ui/mymain.go b/ui/mymain.go
new file mode 100644
index 0000000..27bc825
--- /dev/null
+++ b/ui/mymain.go
@@ -0,0 +1,45 @@
+// feb 2022
+// We are building a version without graphics
+// +build !no_gfx
+
+package ui
+
+import (
+ "fmt"
+ "io"
+ "os"
+
+ "example.com/ackley_mc/mc_work"
+)
+
+// realmain is the real main function. The program wants to read from a file,
+// but we can have it read from an io.Reader and then use the test functions
+// for playing with it.
+func realmain(fp io.Reader) error {
+ var mcPrm mcwork.McPrm
+ if fp != nil {
+ if err := mcwork.RdPrm(fp, &mcPrm); err != nil {
+ return err
+ }
+ } else {
+ if err := getExmpl(&mcPrm); err != nil {
+ return err
+ }
+ }
+ return UiDoRun(&mcPrm)
+
+}
+
+func MyMain() error {
+ if len(os.Args) < 2 {
+ fmt.Println("MyMain did not get a file to work with ")
+ return realmain(nil)
+ }
+ fname := os.Args[1]
+ if fp, err := os.Open(fname); err != nil {
+ return err
+ } else {
+ defer fp.Close()
+ return realmain(fp)
+ }
+}
diff --git a/ui/param_tab.go b/ui/param_tab.go
new file mode 100644
index 0000000..504f283
--- /dev/null
+++ b/ui/param_tab.go
@@ -0,0 +1,182 @@
+// Feb 2022
+// Set up a tab for getting Monte Carlo Parameters
+// This should return an object that can be embedded in a tabbed page.
+//go:build !no_gfx
+// +build !no_gfx
+
+package ui
+
+import (
+ "fmt"
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/data/binding"
+ "fyne.io/fyne/v2/dialog"
+ "fyne.io/fyne/v2/storage"
+ "fyne.io/fyne/v2/widget"
+ "os"
+ "strconv"
+ "strings"
+
+ "example.com/ackley_mc/mc_work"
+)
+
+// fslicestrng makes a nice string from a slice of float32's
+func fslicestrng(f []float32) string {
+ if len(f) == 0 {
+ return ""
+ }
+ s := fmt.Sprintf("%g", f[0])
+ for i := 1; i < len(f); i++ {
+ s += fmt.Sprintf(", %g", f[i])
+ }
+ return s
+}
+
+// str2f32 takes a string and returns a slice of float32's
+func s2f32(s string) ([]float32, error) {
+ y := strings.Split(s, ",")
+ if len(y) < 1 {
+ return nil, fmt.Errorf("no fields found")
+ }
+ x := make([]float32, len(y))
+ for i, s := range y {
+ if r, err := strconv.ParseFloat(strings.TrimSpace(s), 32); err != nil {
+ return nil, fmt.Errorf("tried to parse %v %v", s, err)
+ } else {
+ x[i] = float32(r)
+ }
+ }
+ return x, nil
+}
+
+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.
+func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) {
+
+ iniTmp := binding.BindFloat(&mcPrm.IniTmp)
+ iniTmpEntry := widget.NewEntryWithData(binding.FloatToString(iniTmp))
+ iniTmpLabel := widget.NewLabel("initial temp")
+
+ fnlTmp := binding.BindFloat(&mcPrm.FnlTmp)
+ fnlTmpEntry := widget.NewEntryWithData(binding.FloatToString(fnlTmp))
+ fnlTmpLabel := widget.NewLabel("final temp")
+
+ xDlta := binding.BindFloat(&mcPrm.XDlta)
+ xDltaEntry := widget.NewEntryWithData(binding.FloatToString(xDlta))
+ xDltaLabel := widget.NewLabel("X delta")
+
+ xIniStr := binding.NewString()
+ xIniStr.Set(fslicestrng(mcPrm.XIni))
+ xIniEntry := widget.NewEntryWithData(xIniStr)
+ xIniEntry.OnChanged = func(s string) {
+ x, err := s2f32(s)
+ if err != nil {
+ xIniEntry.SetValidationError(err)
+ } else {
+ mcPrm.XIni = append(mcPrm.XIni[:0], x...)
+ }
+ }
+ xIniEntry.Validator = validateXini
+ xIniLabel := widget.NewLabel("X ini")
+
+ r := container.NewGridWithColumns(2,
+ iniTmpLabel, iniTmpEntry,
+ fnlTmpLabel, fnlTmpEntry,
+ xDltaLabel, xDltaEntry,
+ xIniLabel, xIniEntry)
+ refreshPScreen := func() {
+ iniTmp.Reload()
+ fnlTmp.Reload()
+ xDlta.Reload()
+ xIniEntry.SetText(fslicestrng(mcPrm.XIni))
+ }
+ return r, refreshPScreen
+}
+
+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 {
+ dialog.NewError(err, parent).Show()
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// rdwork is called after the file open dialog gets "OK"
+func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, refreshme func()) error {
+ var e error
+ getmcprm := func(rd fyne.URIReadCloser, err error) {
+ if err != nil {
+ fmt.Println("error given to getmcprm")
+ dialog.NewError(err, parent).Show()
+ e = err
+ return
+ }
+ if rd == nil { // cancelled
+ return
+ }
+ defer rd.Close()
+ if err := mcwork.RdPrm(rd, mcPrm); err != nil {
+ e = err
+ return
+ } else {
+ fmt.Println("I think mcprm is", mcPrm)
+ refreshme()
+ dialog.NewInformation("OK confirmed", "read file, no errors", parent).Show()
+ return
+ }
+ }
+
+ t := dialog.NewFileOpen(getmcprm, parent)
+
+ if cwd, err := os.Getwd(); err == nil {
+ if y, err := storage.ListerForURI(storage.NewFileURI(cwd)); err == nil {
+ t.SetLocation(y) // If there was an error, we just use default location
+ }
+ }
+
+ t.Show() // set an error and see if anybody notices
+ return e
+}
+
+// inputTab sets up the input page. At the top, we have a button to read from
+// a file.
+func inputTab(mcPrm *mcwork.McPrm, parent fyne.Window, chn chan workstatus) (*fyne.Container, error) {
+ paramBinding, refreshPscreen := paramScreen(mcPrm)
+ rdfile := func() {
+ if err := rdwork(mcPrm, parent, refreshPscreen); err != nil {
+ dialog.NewError(err, parent).Show()
+ }
+ }
+ startrun := func() {
+ 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()
+ close(chn)
+ return
+ } else {
+ chn <- workstatus{fdata: fdata, xdata: xdata, status: resultsReady}
+ }
+ }
+ rdfileBtn := widget.NewButton("read file", rdfile)
+ runBtn := widget.NewButton("start run", startrun)
+ buttons := container.NewVBox(rdfileBtn, runBtn)
+ c := container.NewHBox(buttons, paramBinding)
+ return c, nil
+}
diff --git a/ui/scrnplt.go b/ui/scrnplt.go
index 715fc16..ac34c13 100644
--- a/ui/scrnplt.go
+++ b/ui/scrnplt.go
@@ -10,7 +10,6 @@ import (
"fmt"
"fyne.io/fyne/v2"
- "fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
@@ -31,7 +30,6 @@ func tryfsave(uriw fyne.URIWriteCloser, err error, data []byte, parent fyne.Wind
if err := uriw.Close(); err != nil {
fmt.Println("error closing")
}
- fmt.Printf("trydsave called with %+v %+v", uriw, err)
}
func fsave(parent fyne.Window, fdata []byte, suggested string) {
@@ -43,8 +41,6 @@ func fsave(parent fyne.Window, fdata []byte, suggested string) {
t.SetFileName(suggested)
t.SetFilter(filter)
t.Show()
-
- fmt.Println("dsave called and returning")
}
func topmenu(parent fyne.Window, fdata, xdata []byte) *fyne.Menu {
@@ -70,19 +66,15 @@ func fileSaved(f fyne.URIWriteCloser, w fyne.Window) {
func nothing(...interface{}) {}
func breaker(...interface{}) {}
-func Scrnplt(fdata, xdata []byte) {
- a := app.NewWithID("ackley") // Find a way to check if it is happy
- w := a.NewWindow("Monte Carlo")
-
- w.SetMainMenu(fyne.NewMainMenu(topmenu(w, fdata, xdata)))
+func scrnplt(fdata, xdata []byte) *fyne.Container {
fImage := canvas.NewImageFromReader(bytes.NewReader(fdata), "func.png")
fImage.FillMode = canvas.ImageFillContain
xImage := canvas.NewImageFromReader(bytes.NewReader(xdata), "xdata.png")
xImage.FillMode = canvas.ImageFillContain
content := container.NewGridWithRows(2, fImage, xImage)
- w.Resize(fyne.NewSize(500, 600))
- w.SetContent(content)
- w.ShowAndRun()
- fmt.Println("This was executed after the graphics finished")
+// w.Resize(fyne.NewSize(500, 600))
+// w.SetContent(content)
+ // w.ShowAndRun()
+ return content
}
diff --git a/ui/scrnplt.goat b/ui/scrnplt.goat
deleted file mode 100644
index 470aa0e..0000000
--- a/ui/scrnplt.goat
+++ /dev/null
@@ -1,32 +0,0 @@
-// 25 Jan 2020
-// Given a buffer or two with a plot picture, send it to the screen
-
-// I think this might be better in its own package
-package ui
-
-import (
- "bytes"
- "fmt"
- "image/color" // need this for the green ?
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/app"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/container"
-)
-
-func Scrnplt (b []byte) {
- fmt.Println ("scrnplt says buf size", len(b), "first few bytes:", string(b[:10]))
- a := app.New()
- w := a.NewWindow("container")
- image := canvas.NewImageFromReader(bytes.NewReader(b), "boo.svg")
- green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
- text1 := canvas.NewText("Hello", green); print(text1)
- text2 := canvas.NewText("There", green)
- text2.Move(fyne.NewPos(20, 20))
- content := container.NewWithoutLayout( image) // no more text 1, text2
- // content := container.New(layout.NewGridLayout(2), text1, text2)
-
- w.SetContent(content)
-
- w.ShowAndRun()
-}
diff --git a/ui/ui_run.go b/ui/ui_run.go
new file mode 100644
index 0000000..ef2ff0a
--- /dev/null
+++ b/ui/ui_run.go
@@ -0,0 +1,43 @@
+// 25 Jan 2020
+// Given a buffer or two with a plot picture, send it to the screen
+
+// +build !no_gfx
+
+package ui
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/app"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/widget"
+
+ "example.com/ackley_mc/mc_work"
+)
+
+
+func initIn () *widget.Card {
+ return widget.NewCard("input screen", "click on run to start a calc", nil)
+}
+
+func UiDoRun (mcPrm *mcwork.McPrm) error {
+
+ a := app.NewWithID("Monte Carlo")
+ w := a.NewWindow ("Monte Carlo")
+ quitbutton := widget.NewButton ("quit .. click somwhere in here", a.Quit)
+ chn := make(chan workstatus)
+ inputTabCallback := func() (*fyne.Container) {
+ a, _ := inputTab(mcPrm, w, chn)
+ return a
+ }
+ t1 := container.NewTabItem("input tab", inputTabCallback())
+ cntrOut := fyne.NewContainer()
+ t2 := container.NewTabItem("output tab", cntrOut)
+ t3 := container.NewTabItem("quit me", quitbutton)
+ appTab := container.NewAppTabs(t1, t2, t3)
+ w.SetContent(appTab)
+ breaker()
+ go outputTab(chn, cntrOut)
+ w.ShowAndRun()
+ close (chn)
+ return nil
+}
--
GitLab