Select Git revision
Windows activation helper.cmd
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
rdprm.go 2.99 KiB
// Aug 2021
// Read the parameters for a calculation
// We have magic keywords like ini_temp.
// 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 ackwork
import (
"bufio"
"errors"
"fmt"
"io"
"strconv"
"strings"
)
var i int = 6
var cmdDflt = []struct {
key string
v string
}{
{"ini_temp", "20"},
{"final_temp", "1"},
{"n_step", "1000"},
{"n_run", "1"},
{"x_ini", "3,4,5"},
{"x_delta", "0.5"},
{"seed", "1637"},
{"foutname", "mcrun"},
{"fpltname", ""}, // empty means no plots of function
{"xpltname", ""},
{"verbose", ""},
{"dummy", ""},
}
// 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)
}
getu := func(s string) uint32 {
if err != nil {
return 0
}
var u uint64
u, err = strconv.ParseUint(s, 10, 32)
return uint32(u)
}
getx := func(s string) []float32 {
if err != nil {
return nil
}
y := strings.Split(s, ",")
if len(y) < 1 {
err = fmt.Errorf("broke trying to get initial x values")
return nil
}
x := make([]float32, len(y))
for i, s := range y {
r := 0.
if r, err = strconv.ParseFloat(s, 32); err != nil {
return nil
}
x[i] = float32(r)
}
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.fOutName = prmMap["foutname"]
mcPrm.fPltName = prmMap["fpltname"]
mcPrm.xPltName = prmMap["xpltname"]
seed = int64(getu(prmMap["seed"]))
if err != nil { // Only returns the first error encountered
return err
}
if prmMap["verbose"] != "" {
mcPrm.verbose = true
}
if prmMap["dummy"] != "" {
mcPrm.dummy = true
}
return nil
}
// spew spews out an error and known input parameters
func spew() string {
s := `Input file should be of
key value
pairs. Values for x_ini are separated by commas without spaces.
`
for _, ss := range cmdDflt {
s += fmt.Sprintf("%s %s\n", ss.key, ss.v)
}
return s
}
// rdPrmInner is in a function by itself, to make testing easier
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
}
scn := bufio.NewScanner(fp)
for scn.Scan() {
s := scn.Text()
if len(s) == 0 {
continue // blank lines
}
s = strings.ToLower(s)
ss := strings.Fields(s)
if len(ss) < 2 {
return fmt.Errorf("Only one field in line: %s\n%s", s, spew())
}
key := ss[0]
if _, ok := prmMap[key]; !ok {
return fmt.Errorf("unknown keyword \"%s\"\n%s", key, spew())
} else {
prmMap[key] = ss[1]
}
}
if err := scn.Err(); err != nil {
return errors.New(spew())
}
return digest(prmMap, mcPrm)
}