def from_listable(cls, parent, key, listable=None): """ Build a MultipleTraverser by matching `key` against iter(parent) """ if listable is None: listable = parent log.debug("Building MultipleTraverser from key: {0}".format(key)) if "," in key: # Assume list is provided lst = key.split(",") indexed_contexts = [((f, ), parent[f]) for f in lst] slot_filler = getattr(parent, "slot_filler", cls.default_slot_filler) return cls.from_parent(parent, key, indexed_contexts, slot_filler=slot_filler) pattern = re.compile(fnmatch.translate(key)) match = pattern.match indexed_contexts = [((f, ), parent[f]) for f in listable if match(f)] slot_filler = getattr(parent, "slot_filler", cls.default_slot_filler) return cls.from_parent(parent, key, indexed_contexts, slot_filler=slot_filler)
def content(self): # TODO(pwaller): Remove defunct raise/parentage if self.format == "raise": class UserThrow(RuntimeError): pass raise UserThrow("Stopping because you asked me to.") log.debug("Rendering {0} from {1}".format(self.format, self)) params = self.params params.update(self.request.params) resolution = int(params.get("resolution", self.RESOLUTION_DEFAULT)) resolution = min(resolution, self.RESOLUTION_MAX) rootformat = "eps" if self.format == "pdf": rootformat = "pdf" with NamedTemporaryFile(suffix="." + rootformat) as tmpfile: with self.canvas as canvas: self.configure_canvas(params, canvas) self.render(canvas) canvas.Update() try: canvas.SaveAs(tmpfile.name) except ROOTError as err: if "illegal number of points" in err.msg: log.warning('problem plotting canvas "%s", error from ROOT "%s"', canvas.GetName(), err.msg) else: raise log.info("RENDERING {0} -- {1}".format(self.format, rootformat)) if self.format == rootformat: # No conversion necessary, ROOT did it directly. # grab the file from disk with open(tmpfile.name) as eps_fd: content = eps_fd.read() else: # convert_eps releases the GIL by doing the work off-process. # This is where the speed comes from. content = convert_eps(tmpfile.name, resolution, self.format) # print "Made EPS: {0:5.2f} content = {1:5.2f}".format(len(epsdata) / # 1024., len(content) / 1024.) extra_args = {} if "attach" in params: log.error("Attaching rendered image") # Give the file a sensible name, rather than the last fragment # of the URL which was visited. extra_args.update(content_disposition=( "Content-Disposition: attachment; filename={0};" .format(self.filename))) return Response(content, content_type="image/{0}".format(self.format), **extra_args)
def canvas(self): # We need a thread-specific name, otherwise if two canvases exist with the # same name we can get a crash with RootRenderer.global_canvas_lock: # TODO(pwaller): Investigate removing this kludge now we have # a global canvas lock canvas_name = str(get_ident()) + str(randint(0, int(1e14))) log.debug("Operating with canvas {0} ({1} alive)" .format(canvas_name, len(R.gROOT.GetListOfCanvases()))) assert not R.gROOT.GetListOfCanvases().FindObject(canvas_name), ( "Canvas collision") c = R.TCanvas(canvas_name) # Rendering code gets run here. yield c # Make the canvas go away immediately. # Don't wait for GC. c.IsA().Destructor(c)
def canvas(self): # We need a thread-specific name, otherwise if two canvases exist with the # same name we can get a crash with RootRenderer.global_canvas_lock: # TODO(pwaller): Investigate removing this kludge now we have # a global canvas lock canvas_name = str(get_ident()) + str(randint(0, int(1e14))) log.debug("Operating with canvas {0} ({1} alive)".format( canvas_name, len(R.gROOT.GetListOfCanvases()))) assert not R.gROOT.GetListOfCanvases().FindObject(canvas_name), ( "Canvas collision") c = R.TCanvas(canvas_name) # Rendering code gets run here. yield c # Make the canvas go away immediately. # Don't wait for GC. c.IsA().Destructor(c)
def from_listable(cls, parent, key): """ Build a MultipleTraverser by matching `key` against iter(parent) """ log.debug("Building MultipleTraverser from key: {0}".format(key)) if "," in key: # Assume list is provided lst = key.split(",") indexed_contexts = [((f,), parent[f]) for f in lst] slot_filler = getattr(parent, "slot_filler", cls.default_slot_filler) return cls.from_parent(parent, key, indexed_contexts, slot_filler=slot_filler) pattern = re.compile(fnmatch.translate(key)) match = pattern.match indexed_contexts = [((f,), parent[f]) for f in parent if match(f)] slot_filler = getattr(parent, "slot_filler", cls.default_slot_filler) return cls.from_parent(parent, key, indexed_contexts, slot_filler=slot_filler)
def __init__(self, request, stack, composition_type): super(Combination, self).__init__(request) self.stack = stack self.composition_type = composition_type # object_types = # print "Object types:", object_types # assert len(object_types) == 1, "Tried to combine objects of differen types?" # stack_type = object_types.pop() # if not issubclass(stack_type, Renderable): # print "Can't combine:", stack_type # raise NotImplementedError() # return # print "Combinable!", stack_type if self.composition_type == "stack": self.renderer = CombinationStackRenderer if self.composition_type == "dual": self.renderer = CombinationDualRenderer if self.composition_type == "ebke": self.renderer = EbkeCombinationStackRenderer if self.composition_type == "eff": self.renderer = CombinationEffRenderer if self.composition_type == "diff": self.renderer = CombinationDiffRenderer if self.composition_type == "div": self.renderer = CombinationDivRenderer log.debug("Using renderer: {0}".format(self.renderer))
def renderer_view(context, request): log.debug("renderer_view {0}".format(context)) return context.content
def __init__(self, request, resource_to_render, format, params=None): super(Renderer, self).__init__(request) log.debug("New {0} renderer {1}".format(format, resource_to_render)) self.resource_to_render = resource_to_render self.format = format self.params = params or {}
def content(self): # TODO(pwaller): Remove defunct raise/parentage if self.format == "raise": class UserThrow(RuntimeError): pass raise UserThrow("Stopping because you asked me to.") log.debug("Rendering {0} from {1}".format(self.format, self)) params = self.params params.update(self.request.params) resolution = int(params.get("resolution", self.RESOLUTION_DEFAULT)) resolution = min(resolution, self.RESOLUTION_MAX) rootformat = "eps" if self.format == "pdf": rootformat = "pdf" with NamedTemporaryFile(suffix="." + rootformat) as tmpfile: with self.canvas as canvas: self.configure_canvas(params, canvas) self.render(canvas) canvas.Update() try: canvas.SaveAs(tmpfile.name) except ROOTError as err: if "illegal number of points" in err.msg: log.warning( 'problem plotting canvas "%s", error from ROOT "%s"', canvas.GetName(), err.msg) else: raise log.info("RENDERING {0} -- {1}".format(self.format, rootformat)) if self.format == rootformat: # No conversion necessary, ROOT did it directly. # grab the file from disk with open(tmpfile.name) as eps_fd: content = eps_fd.read() else: # convert_eps releases the GIL by doing the work off-process. # This is where the speed comes from. content = convert_eps(tmpfile.name, resolution, self.format) # print "Made EPS: {0:5.2f} content = {1:5.2f}".format(len(epsdata) / # 1024., len(content) / 1024.) extra_args = {} if "attach" in params: log.error("Attaching rendered image") # Give the file a sensible name, rather than the last fragment # of the URL which was visited. extra_args.update(content_disposition=( "Content-Disposition: attachment; filename={0};".format( self.filename))) return Response(content, content_type="image/{0}".format(self.format), **extra_args)
def render(self, canvas): params = self.request.params names, histograms = zip(*self.resource_to_render.stack) # print "Rendering stack with {0} histograms".format(len(histograms)) names = [n for n in names] histograms = [h for h in histograms] objs = [h.obj for h in histograms] if "sum" in params: hsum = objs[0].Clone("sum") keepalive(canvas, hsum) hsum.SetTitle("sum") for h in objs[1:]: hsum.Add(h) names.append("sum") objs.append(hsum) colordict = { "all": R.kBlue, "signal": R.kGreen, "fake": R.kRed, } cols = [R.kBlue, R.kRed, R.kGreen, R.kViolet, R.kAzure + 6, R.kOrange] for name, obj, col in zip(names, objs, cols): col = col + 1 # obj.SetTitle(""); obj.SetStats(False) if name in colordict: obj.SetLineColor(colordict[name]) else: obj.SetLineColor(col) obj.SetMarkerColor(col) obj.SetLineWidth(2) if "shape" in params: for obj in objs: if obj.Integral(): obj.Scale(1. / obj.Integral()) max_value = max(o.GetMaximum() for o in objs) * 1.1 min_value = min(o.GetMinimum() for o in objs) if min_value != objs[0].GetMinimum(): old_minvalue = min_value # Apply a correction to include a bit more than just the lower bound min_value = min_value - (max_value - min_value) * 0.1 # If this takes us below zero but the old minimum value was close # to zero, just use zero. if min_value < 0 and abs(old_minvalue) < 1e-8: min_value = 0 obj = objs[0] # .pop(0) from root.histogram import build_draw_params dp = "hist e0x0" # build_draw_params(obj, self.request.params, True) obj.Draw(dp) obj.SetMaximum(max_value) # obj.SetMinimum(0) for obj in objs[1:]: obj.Draw(dp + " same") logy = canvas.GetLogy() canvas.SetLogy(False) canvas.Update() canvas_yrange = ymin, ymax = canvas.GetUymin(), canvas.GetUymax() canvas.SetLogy(logy) canvas.Update() def line(x, yrange): ymin, ymax = yrange args = x, ymin, x, ymax l = R.TLine(*args) l.SetLineWidth(3) l.SetLineStyle(2) l.Draw() keepalive(canvas, l) # Draw cuts slot = self.request.params.get("slot", None) if not slot: # Determine slot from path for p in lineage(self): if p.__name__ in cuts: slot = p.__name__ if slot: for x, yrange in zip(cuts[slot], zip(etabins, etabins[1:])): if canvas.GetUxmin() < x < canvas.GetUxmax(): line(x, canvas_yrange if obj.GetDimension() != 2 else yrange) if self.request.params.get("legend", None) is not None: log.debug("Drawing legend: {0}".format(objs)) for n, o in zip(names, objs): o.SetTitle(n) legend = get_legend(mc=objs) legend.Draw()