Beispiel #1
0
func doFlowGraph(cmd string, args []string) {
	fs := flag.NewFlagSet("flowgraph", flag.ExitOnError)
	fs.Usage = func() {
		log.Print("Usage: flowgraph")
		log.Printf("%v\n", cmds.Help(cmd))
		fs.PrintDefaults()
	}
	proto := fs.Bool("proto", false, "aggregate nodes by prototype")
	t0 := fs.Int("t1", 0, "beginning of time interval (default is beginning of simulation)")
	t1 := fs.Int("t2", -1, "end of time interval (default if end of simulation)")
	fs.Parse(args)
	initdb()

	arcs, err := query.FlowGraph(db, simid, *t0, *t1, *proto)
	fatalif(err)

	fmt.Println("digraph ResourceFlows {")
	fmt.Println("    overlap = false;")
	fmt.Println("    nodesep=1.0;")
	fmt.Println("    edge [fontsize=9];")
	for _, arc := range arcs {
		fmt.Printf("    \"%v\" -> \"%v\" [label=\"%v\\n(%.3g kg)\"];\n", arc.Src, arc.Dst, arc.Commod, arc.Quantity)
	}
	fmt.Println("}")
}
Beispiel #2
0
func uploadInner(w http.ResponseWriter, r *http.Request, kill chan bool) {
	// parse database from multi part form data
	if err := r.ParseMultipartForm(MAX_MEMORY); err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusForbidden)
		return
	}

	gotDb := false
	uid := r.URL.Path[len("/upload/"):]
	fname := uid + ".sqlite"
	for _, fileHeaders := range r.MultipartForm.File {
		for _, fileHeader := range fileHeaders {
			file, _ := fileHeader.Open()
			data, _ := ioutil.ReadAll(file)
			err := ioutil.WriteFile(fname, data, 0644)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				log.Print(err)
				return
			}
			defer func() { os.Remove(fname) }()
			gotDb = true
			break
		}
		break
	}
	if !gotDb {
		http.Error(w, "No file provided", http.StatusBadRequest)
		log.Print("received request with no file")
		return
	}

	select {
	case <-kill:
		return
	default:
	}

	// post process the database
	db, err := sql.Open("sqlite3", fname)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	defer db.Close()

	err = post.Prepare(db)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	defer post.Finish(db)

	simids, err := post.GetSimIds(db)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}

	ctx := post.NewContext(db, simids[0])
	if err := ctx.WalkAll(); err != nil {
		log.Println(err)
	}

	// get simid
	ids, err := query.SimIds(db)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	simid := ids[0]
	rs := &Results{}

	select {
	case <-kill:
		return
	default:
	}

	// create flow graph
	combineProto := false
	arcs, err := query.FlowGraph(db, simid, 0, -1, combineProto)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	dotname := fname + ".dot"
	dotf, err := os.Create(dotname)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	defer func() { os.Remove(dotname) }()

	fmt.Fprintln(dotf, "digraph ResourceFlows {")
	fmt.Fprintln(dotf, "    overlap = false;")
	fmt.Fprintln(dotf, "    nodesep=1.0;")
	fmt.Fprintln(dotf, "    edge [fontsize=9];")
	for _, arc := range arcs {
		fmt.Fprintf(dotf, "    \"%v\" -> \"%v\" [label=\"%v\\n(%.3g kg)\"];\n", arc.Src, arc.Dst, arc.Commod, arc.Quantity)
	}
	fmt.Fprintln(dotf, "}")
	dotf.Close()

	var buf bytes.Buffer
	cmd := exec.Command("dot", "-Tsvg", dotname)
	cmd.Stdout = &buf
	err = cmd.Run()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	rs.Flowgraph = buf.String()

	select {
	case <-kill:
		return
	default:
	}

	// create agents table
	rs.Agents, err = query.AllAgents(db, simid, "")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}

	// create Material transactions table
	sql := `
		SELECT TransactionId,Time,SenderId,ReceiverId,tr.ResourceId,Commodity,NucId,MassFrac*Quantity
		FROM Transactions AS tr
		INNER JOIN Resources AS res ON tr.ResourceId = res.ResourceId
		INNER JOIN Compositions AS cmp ON res.QualId = cmp.QualId
		WHERE tr.SimId = ? AND cmp.SimId = res.SimId AND res.SimId = tr.SimId
		AND res.Type = 'Material';
		`
	rows, err := db.Query(sql, simid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}

	for rows.Next() {
		t := &Trans{}
		if err := rows.Scan(&t.Id, &t.Time, &t.Sender, &t.Receiver, &t.ResourceId, &t.Commod, &t.Nuc, &t.Qty); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			log.Print(err)
			return
		}
		rs.TransMats = append(rs.TransMats, t)
	}
	if err := rows.Err(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}

	// create Material transactions table
	sql = `
		SELECT TransactionId,Time,SenderId,ReceiverId,tr.ResourceId,Commodity,Quality,Quantity
		FROM Transactions AS tr
		INNER JOIN Resources AS res ON tr.ResourceId = res.ResourceId
		INNER JOIN Products AS pd ON res.QualId = pd.QualId
		WHERE tr.SimId = ? AND pd.SimId = res.SimId AND res.SimId = tr.SimId
		AND res.Type = 'Product';
		`
	rows, err = db.Query(sql, simid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}

	for rows.Next() {
		t := &ProdTrans{}
		if err := rows.Scan(&t.Id, &t.Time, &t.Sender, &t.Receiver, &t.ResourceId, &t.Commod, &t.Quality, &t.Qty); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			log.Print(err)
			return
		}
		rs.TransProds = append(rs.TransProds, t)
	}
	if err := rows.Err(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}

	select {
	case <-kill:
		return
	default:
	}

	// render all results and save page
	rs.Uid = uid
	resultTmpl.Execute(w, rs)

	f, err := os.Create(uid + ".html")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Print(err)
		return
	}
	defer f.Close()
	resultTmpl.Execute(f, rs)
	close(kill)
}
Beispiel #3
0
func doTaint(cmd string, args []string) {
	fs := flag.NewFlagSet(cmd, flag.ExitOnError)
	fs.Usage = func() {
		log.Printf("Usage: %v", cmd)
		log.Printf("%v\n", cmds.Help(cmd))
		fs.PrintDefaults()
	}
	t := fs.Int("t", -1, "time step for which to print taint")
	res := fs.Int("res", -1, "resource ID of object to track")
	fs.Parse(args)
	initdb()

	if *t == -1 || *res == -1 {
		log.Fatalf("'-t' and '-res' flags are both required and cannot be negative")
	}

	roots := taint.TreeFromDb(db, simid)
	var base *taint.Node
	visited := taint.Visited{}
	for _, root := range roots {
		if base = root.Locate(visited, *res); base != nil {
			break
		}
	}
	if base == nil {
		log.Fatalf("couldn't find resource id %v in graph", *res)
	}

	si, err := query.SimStat(db, simid)
	fatalif(err)
	taints := base.Taint(si.Duration)

	// print graph dot file
	byproto := false
	t1, t2 := 0, -1
	arcs, err := query.FlowGraph(db, simid, t1, t2, byproto)
	fatalif(err)

	fmt.Println("digraph ResourceFlows {")
	fmt.Println("    overlap = false;")
	fmt.Println("    nodesep=1.0;")
	fmt.Println("    edge [fontsize=9];")
	for _, arc := range arcs {
		var srctaint taint.TaintVal
		if ts := taints[arc.SrcId]; *t < len(ts) {
			srctaint = ts[*t]
		} else if len(ts) > 0 {
			srctaint = ts[len(ts)-1]
		}
		var dsttaint taint.TaintVal
		if ts := taints[arc.DstId]; *t < len(ts) {
			dsttaint = ts[*t]
		} else if len(ts) > 0 {
			dsttaint = ts[len(ts)-1]
		}

		srccolor := byte(255 * (1 - math.Pow(srctaint.Taint*srctaint.Quantity/base.Quantity, 1.0/5)))
		dstcolor := byte(255 * (1 - math.Pow(dsttaint.Taint*dsttaint.Quantity/base.Quantity, 1.0/5)))
		srcname := fmt.Sprintf("%v %v\\n(%.3e kg of %.4f taint)", arc.SrcProto, arc.SrcId, srctaint.Quantity, srctaint.Taint)
		dstname := fmt.Sprintf("%v %v\\n(%.3e kg of %.4f taint)", arc.DstProto, arc.DstId, dsttaint.Quantity, dsttaint.Taint)

		fmt.Printf("    \"%v\" [style=filled, fillcolor=\"#FF%.2X%.2X\"];\n", srcname, srccolor, srccolor)
		fmt.Printf("    \"%v\" [style=filled, fillcolor=\"#FF%.2X%.2X\"];\n", dstname, dstcolor, dstcolor)
		fmt.Printf("    \"%v\" -> \"%v\" [label=\"%v\"];\n", srcname, dstname, arc.Commod)
	}
	fmt.Println("}")
}