def process(self, parentage): """ Draws the histogram corresponding to the present cut and optionally the weighting strategy. Args: parentage: the names of the call stack Returns: a tuple (Hist, Node.process()) with the projected histogram Hist and the parent Node class process output. """ r = Node.process(self, parentage) # sys.stdout.write("+") # sys.stdout.flush() #Use the cache of the previous CutNode in the call stack. cache = self.getPreviousCache(parentage) #Get the total cut string from the call stack. cut = self.getPrevious(parentage, lambda x: hasattr(x, "getCutsTotal")).\ getCutsTotal(parentage) #Get the total weight weights = self.getParents(parentage, lambda x: hasattr(x, "weight")) wtot = mul([w.weight for w in weights]) if not "var" in self.hist_desc.keys() or not "binning" in self.hist_desc.keys(): raise KeyError("Incorrect hist desc: %s" % str(self.hist_desc)) #Get the sample node snodes = self.getParents(parentage, lambda x: hasattr(x, "sample")) if not len(snodes)==1: raise Exception("More than one parent was a SampleNode, undefined behaviour (probably human error).") snode = snodes[0] hi = snode.sample.drawHistogram(self.hist_desc["var"], str(cut), weight=wtot.weight_str, binning=self.hist_desc["binning"], entrylist=cache) hdir = self.parentsName(parentage) #Scale MC histograms to 1 inverse picobarn if snode.sample.isMC: hi.Scale(snode.sample.lumiScaleFactor(1)) line_to_show = [ "->".join([p.name for p in parentage]+[self.name]), hi.GetEntries(), cache.GetN(), "%.2f" % hi.Integral() ] self.logger.info( ", ".join(map(lambda x: str(x), line_to_show)) ) hi.SetName(self.name) snode.saver.save(hdir, hi) return (hi, r)
def syst_weights(graph): _syst_weights = [] for lepton, w in weights_lepton.items(): weights_var_by_one = variateOneWeight([x[1] for x in (weights_syst+w)]) # The unvariated weight is taken as the list of the 0th elements of the # weight tuples weights_var_by_one.append( ("nominal", [x[1][0] for x in (weights_syst+w)]) ) wtot = [] for wn, s in weights_var_by_one: j = mul(s) #Multiply together the list of weights wtot.append((wn, j)) for name, j in wtot: filter_funcs=[ #Apply the weights separately for the lepton channels lambda _x,_lepton=lepton: is_chan(_x, _lepton), #Apply only in MC is_mc ] #Apply systematic weights only in case of nominal samples if name != "nominal": filter_funcs += [ #Check if the parent was a nominal sample lambda _x: "/nominal/" in _x[0].name ] syst = WeightNode( j, graph, "weight__" + name + "__" + lepton, [], [], filter_funcs=filter_funcs ) logger.debug("Appending weight %s" % syst.name) _syst_weights.append(syst) #Always produce the unweighted plot unw = WeightNode( Weights.no_weight, graph, "weight__unweighted", [], [] ) _syst_weights.append(unw) return _syst_weights