diff --git a/python/BlackDynamite/graphhelper.py b/python/BlackDynamite/graphhelper.py index 5b06a80..351cf41 100644 --- a/python/BlackDynamite/graphhelper.py +++ b/python/BlackDynamite/graphhelper.py @@ -1,274 +1,277 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -*- py-which-shell: "python"; -*- import base import run import job import runselector import jobselector import matplotlib.pyplot as plt import re import bdparser import sys import run import numpy as np class GraphHelper(object): """ """ def getMeasures(self,run_list): myresults = [] for r,j in run_list: print ("retreive data from run " + r["run_name"]) res = r.getScalarQuantities(self.quantities) for key , value in res: if (value == None): del res[key] myresults.append([r,j,res]) return myresults def selectGraphs(self): run_list = self.runSelector.selectRuns(self.run_constraints,self.job_constraints, self.sort_by) results = self.getMeasures(run_list) return results - def makeGraphs(self,**kwargs): + def makeGraphs(self,fig=None,**kwargs): results = self.selectGraphs() - fig = plt.figure() + if (not fig): + fig = plt.figure() for r,j,data in results: self.makeCurve(data,fig=fig,myrun=r,myjob=j,**kwargs) - + return fig def replaceRunAndJobsParameters(self,name,myrun,myjob): res = name # print (res) codes = [["%r."+key,myrun[key]] for key in myrun.entries.keys()] codes += [["%j."+key,myjob[key]] for key in myjob.entries.keys()] for code,val in codes: res = res.replace(code,str(val)) return res def generateLabels(self,results,myrun,myjob): labels = [] names = [r[0] for r in results] for i in range(0,len(results)): name = results[i][0] if (not self.legend or i >= len(self.legend) or not self.legend[i]): labels.append(name) continue # print (self.legend[i]) - head_legend = re.sub(r"(%)([0-9]+)",r'{\2}',self.legend[i]).format(*names) + head_legend = self.legend[i].replace("{","{{") + head_legend = head_legend.replace("}","}}") + head_legend = re.sub(r"(%)([0-9]+)",r'{\2}',head_legend).format(*names) # print (head_legend) head_legend = self.replaceRunAndJobsParameters(head_legend,myrun,myjob) # print (head_legend) # if (not head_legend.find("%") == -1): # print("unknown variable name. Possible variables are:") # print "\n".join([c[0] for c in codes]) # sys.exit(-1) # print (head_legend) labels.append(head_legend) return labels def makeComposedQuantity(self,results,myrun,myjob): vecs = [r[1] for r in results] names = [r[0] for r in results] # print (vecs[0].shape) new_results = [] for comp in self.using: exprs = comp.split(":") tmp_res = [] for i in [0,1]: e = re.sub(r"(%)([0-9]+)\.(x)",r"vecs[\2][:,0]",exprs[i]) e = re.sub(r"(%)([0-9]+)\.(y)",r"vecs[\2][:,1]",e) e = self.replaceRunAndJobsParameters(e,myrun,myjob) try: tmp_res.append(eval(e)) except: print (names) print ("invalid expression: '" + exprs[i] + "'") print ("invalid expression: '" + e + "'") sys.exit(-1) name = re.sub(r"(%)([0-9]+)\.([x|y])",r'(" + str(names[\2]) + ")',exprs[1]) res = np.zeros((tmp_res[0].shape[0],2)) res[:,0] = tmp_res[0] res[:,1] = tmp_res[1] # print (res.shape) expr = re.sub(r"(%)([0-9]+)",r"vecs[\2]",comp) # res[0] = eval(expr) # print (name) name = "\"" + name + "\"" # print (name) name = eval(name) # print (name) new_results.append([name,res]) return new_results def makeCurve(self,results,myrun=None,myjob=None,fig=None,**kwargs): if (not fig): fig = plt.figure() axe=fig.add_subplot(1,1,1) if self.xrange: axe.set_xlim(self.xrange) if self.yrange: axe.set_ylim(self.yrange) if (self.xlabel): axe.set_xlabel(self.xlabel,fontsize=20) if (self.ylabel): axe.set_ylabel(self.ylabel,fontsize=20) if (self.title): fig.suptitle(self.title) axe.grid(True,linewidth=0.1) if (self.using): results = self.makeComposedQuantity(results,myrun,myjob) labels = self.generateLabels(results,myrun,myjob) # print (labels) for i in range(0,len(results)): name = results[i][0] vec = results[i][1] label = labels[i] # print (self.quantities) # print (name) axe.plot(vec[:,0]/self.xscale, vec[:,1]/self.yscale,label=label) axe.legend(loc='best') if (self.fileout): fig.savefig(self.fileout) return fig def setJobConstraint(self,**params): self.job_constraints = [] if ("job_constraints" in params): self.job_constraints = params["job_constraints"] def setRunConstraint(self,**params): self.run_constraints = [] if ("run_constraints" in params): self.run_constraints = params["run_constraints"] def setQuantity(self,**params): if ("quantity" in params): self.quantities = params["quantity"] else: print ("quantity should be provided using option --quantity") self.quantities = "__BLACKDYNAMITE_ERROR__" def __init__ (self,base,**params): self.setJobConstraint(**params) self.setRunConstraint(**params) self.sort_by = None if ("sort_by" in params): self.sort_by = params["sort_by"] self.setQuantity(**params) self.base = base self.runSelector = runselector.RunSelector(self.base) self.legend = None self.fig = None self.xrange = None self.yrange = None self.xlabel = None self.ylabel = None self.xscale = 1. self.yscale = 1. self.fileout = None self.title = None self.using = None if("legend" in params): self.legend = params["legend"] if("xrange" in params): self.xrange = params["xrange"] if("yrange" in params): self.yrange = params["yrange"] if("xlabel" in params): self.xlabel = params["xlabel"] if("ylabel" in params): self.ylabel = params["ylabel"] if("xscale" in params): self.xscale = params["xscale"] if("yscale" in params): self.yscale = params["yscale"] if("fileout" in params): self.fileout = params["fileout"] if("title" in params): self.title = params["title"] if("using" in params): self.using = params["using"] if("list_quantities" in params): myrun = run.Run(base) print ("list of possible quantities:\n") print("\n".join(myrun.listQuantities())) sys.exit(0) ################################################################ class GraphParser(bdparser.BDParser): """ """ def declareBDParameters(self,additional_params=None,default_additional_params=None): tmp_params = self.graph_params if (additional_params): tmp_params.update(additional_params) bdparser.BDParser.declareBDParameters(self,additional_params=tmp_params,default_additional_params=default_additional_params) def __init__ (self): bdparser.BDParser.__init__(self) self.graph_params = {} self.graph_params["quantity"] = [str] self.graph_params["xrange"] = [float] self.graph_params["yrange"] = [float] self.graph_params["run_constraints"] = [str] self.graph_params["job_constraints"] = [str] self.graph_params["sort_by"] = [str] self.graph_params["xlabel"] = str self.graph_params["ylabel"] = str self.graph_params["xscale"] = float self.graph_params["yscale"] = float self.graph_params["title"] = str self.graph_params["legend"] = [str] self.graph_params["using"] = [str] self.graph_params["list_quantities"] = None ################################################################