Skip to content

Commit

Permalink
Added decom,version subcommands. Improved usage msg...
Browse files Browse the repository at this point in the history
Also no longer require a -db flag/arg if -query is being called.
  • Loading branch information
rwcarlsen committed Dec 17, 2015
1 parent 8eded7e commit addbfce
Showing 1 changed file with 114 additions and 33 deletions.
147 changes: 114 additions & 33 deletions cmd/cyan/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"log"
"os"
"os/exec"
"runtime/pprof"
"strconv"
"strings"
"text/tabwriter"
Expand Down Expand Up @@ -63,27 +62,36 @@ func plot(data *bytes.Buffer, style string, xlabel, ylabel, title string) {
}

func init() {
cmds.Register("post", "Just post process the database", doPost)
cmds.Register("infile", "Show the simulation's input file", doInfile)
cmds.Register("sims", "List all simulations in the database", doSims)
cmds.Register("agents", "List all agents in the simulation", doAgents)
cmds.Register("protos", "List all prototypes in the simulation", doProtos)
cmds.Register("commods", "Show commodities with respective transaction counts and quantities", doCommods)
cmds.Register("trans", "Time series of transactions over time (by quantity)", doTrans)
cmds.Register("power", "Time series of power produced", doPower)
cmds.Register("deployed", "Time series of a prototype's total active deployments", doDeployed)
cmds.Register("built", "Time series of a new builds of a prototype", doBuilt)
cmds.Register("inv", "Time series of agents' inventory", doInv)
cmds.Register("flow", "Time series of material transacted between agents", doFlow)
cmds.Register("flowgraph", "Generate a graphviz dotfile graph of resource flows between agents", doFlowGraph)
cmds.Register("energy", "Thermal energy (J) generated by the simulation between 2 timesteps", doEnergy)
cmds.Register("created", "Material created by one or more agents between specific timesteps", doCreated)
cmds.Register("table", "Show the contents of a specific table", doTable)
cmds.Register("ts", "Investigate any/all time series data", doTimeSeries)
cmds.RegisterDiv("General")
cmds.Register("sims", "list all simulations in the database", doSims)
cmds.Register("infile", "show the simulation's input file", doInfile)
cmds.Register("version", "show simulation's cyclus version info", doVersion)
cmds.Register("post", "post process the database", doPost)
cmds.Register("table", "show the contents of a specific table", doTable)
cmds.Register("ts", "investigate time-series data tables", doTimeSeries)
cmds.RegisterDiv("Agents")
cmds.Register("agents", "list all agents in the simulation", doAgents)
cmds.Register("protos", "list all prototypes in the simulation", doProtos)
cmds.Register("deployed", "time series total active deployments by prototype", doDeployed)
cmds.Register("built", "time series of new builds by prototype", doBuilt)
cmds.Register("decom", "time series of a decommissionings by prototype", doDecom)
cmds.RegisterDiv("Flow")
cmds.Register("commods", "show commodity transaction counts and quantities", doCommods)
cmds.Register("flow", "time series of material transacted between agents", doFlow)
cmds.Register("flowgraph", "generate a graphviz dot script of flows between agents", doFlowGraph)
cmds.Register("trans", "time series of transaction quantity over time", doTrans)
cmds.RegisterDiv("Other")
cmds.Register("inv", "time series of inventory by prototype", doInv)
cmds.Register("power", "time series of power produced", doPower)
cmds.Register("energy", "thermal energy (J) generated between 2 timesteps", doEnergy)
cmds.Register("created", "material created by agents between 2 timesteps", doCreated)
}

func initdb() {
if *dbname == "" {
if *showquery {
// don't need a database for printing queries
return
} else if *dbname == "" {
log.Fatal("must specify database with -db flag")
}

Expand All @@ -105,31 +113,26 @@ func initdb() {
post.Process(db)
}

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {
log.SetFlags(0)
flag.CommandLine.Usage = func() {
fmt.Println("Usage: cyan [-db <cyclus-db>] [flags...] <command> [flags...] [args...]")
fmt.Println("Usage: cyan [-db <cyclus-db>] [flags...] <subcommand> [flags...] [args...]")
fmt.Println("Computes metrics for cyclus simulation data in a sqlite database.")
fmt.Println("\nOptions:")
flag.CommandLine.PrintDefaults()
fmt.Println("\nSub-commands:")
tw := tabwriter.NewWriter(os.Stdout, 2, 2, 2, ' ', 0)
for i := range cmds.Names {
fmt.Printf(" %v: %v\n", cmds.Names[i], cmds.Helps[i])
if cmds.IsDiv(i) {
fmt.Fprintf(tw, "\n\t[%v]\n", cmds.Names[i])
} else {
fmt.Fprintf(tw, "\t\t%v\t%v\n", cmds.Names[i], cmds.Helps[i])
}
}
tw.Flush()
}
flag.Parse()

if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}

if flag.NArg() < 1 {
fmt.Println("Usage: cyan -db <cyclus-db> [flags...] <command> [flags...] [args...]")
fmt.Println("Computes metrics for cyclus simulation data in a sqlite database.")
Expand Down Expand Up @@ -230,6 +233,36 @@ JOIN DecayMode AS d ON i.SimId=d.SimId
doCustom(os.Stdout, cmd)
}

func doVersion(cmd string, args []string) {
fs := flag.NewFlagSet(cmd, flag.ExitOnError)
av := fs.Bool("agent", false, "show simulation's agent versions instead")
fs.Usage = func() {
log.Printf("Usage: %v", cmd)
log.Printf("%v\n", cmds.Help(cmd))
fs.PrintDefaults()
}
fs.Parse(args)
initdb()
s := `
SELECT
i.CyclusVersionDescribe AS Cyclus,
i.SqliteVersion As SQLite,
i.Hdf5Version AS HDF5,
i.BoostVersion AS Boost,
i.LibXML2Version AS libxml2,
i.CoinCBCVersion AS CoinCBC,
x.LibXMLPlusPlusVersion AS 'libxml++'
FROM info AS i
JOIN xmlppinfo AS x ON i.simid=x.simid
WHERE i.simid=?
`
if *av {
s = `SELECT Spec AS Archetype,Version FROM AgentVersions WHERE simid=?`
}
customSql[cmd] = s
doCustom(os.Stdout, cmd, simid)
}

func doPost(cmd string, args []string) {
fs := flag.NewFlagSet(cmd, flag.ExitOnError)
fs.Usage = func() {
Expand Down Expand Up @@ -463,7 +496,7 @@ FROM timelist AS tl
LEFT JOIN (
SELECT a.simid,tl.time AS time,COUNT(a.agentid) AS n
FROM agents AS a
JOIN timelist AS tl ON tl.time=a.entertime
JOIN timelist AS tl ON tl.time=a.entertime AND tl.simid=a.simid
WHERE a.simid=? AND a.prototype=?
GROUP BY time
) AS sub ON tl.time=sub.time AND tl.simid=sub.simid
Expand All @@ -480,6 +513,44 @@ WHERE tl.simid=?
}
}

func doDecom(cmd string, args []string) {
fs := flag.NewFlagSet(cmd, flag.ExitOnError)
fs.Usage = func() {
log.Printf("Usage: %v <prototype>", cmd)
log.Printf("%v\n", cmds.Help(cmd))
fs.PrintDefaults()
}
plotit := fs.Bool("p", false, "plot the data")
fs.Parse(args)
if fs.NArg() < 1 {
log.Fatal("must specify a prototype")
}
initdb()

proto := fs.Arg(0)
s := `
SELECT tl.time AS Time,ifnull(sub.n, 0) AS N_Built
FROM timelist AS tl
LEFT JOIN (
SELECT a.simid,tl.time AS time,COUNT(a.agentid) AS n
FROM agents AS a
JOIN timelist AS tl ON tl.time=a.exittime AND tl.simid=a.simid
WHERE a.simid=? AND a.prototype=?
GROUP BY time
) AS sub ON tl.time=sub.time AND tl.simid=sub.simid
WHERE tl.simid=?
`

customSql[cmd] = s
var buf bytes.Buffer
doCustom(&buf, cmd, simid, proto, simid)
if *plotit {
plot(&buf, "impulses", "Time (Months)", "Number "+proto+" Decommissioned", "Facilities Decommissioned")
} else {
fmt.Print(buf.String())
}
}

func doProtos(cmd string, args []string) {
fs := flag.NewFlagSet(cmd, flag.ExitOnError)
fs.Usage = func() {
Expand Down Expand Up @@ -773,6 +844,11 @@ func NewCmdSet() *CmdSet {
return &CmdSet{funcs: map[string]func(string, []string){}}
}

func (cs *CmdSet) IsDiv(i int) bool {
_, ok := cs.funcs[cs.Names[i]]
return !ok
}

func (cs *CmdSet) Help(cmd string) string {
for i := range cs.Names {
if cs.Names[i] == cmd {
Expand All @@ -782,6 +858,11 @@ func (cs *CmdSet) Help(cmd string) string {
return ""
}

func (cs *CmdSet) RegisterDiv(name string) {
cs.Names = append(cs.Names, name)
cs.Helps = append(cs.Helps, "")
}

func (cs *CmdSet) Register(name, brief string, f func(string, []string)) {
cs.Names = append(cs.Names, name)
cs.Helps = append(cs.Helps, brief)
Expand Down

0 comments on commit addbfce

Please sign in to comment.