def cutflow(cuts, processes, relative=False, weighed=False, f=sys.stdout): expanded_proc = [] procs = [] for proc in processes: subs = [p for p in Process.expand(proc) if str(p) in cuts[0].processes()] if len(subs) > 0: expanded_proc.append(subs) procs.append(proc) cutdata = [[sum(float(cut[p]) for p in ps) for ps in expanded_proc] for cut in cuts] if weighed: for n, c in enumerate(reversed(cuts)): if not isinstance(c, StaticCut): break ratios = [a / (b if b != 0 else 1) for a, b in zip(cutdata[-1], cutdata[-(n + 1)])] cutdata = cutdata[:-n] for i in xrange(3, len(cutdata)): cutdata[i] = [a * b for a, b in zip(cutdata[i], ratios)] if relative: for i in xrange(1, len(cutdata)): cutdata[-i] = [(float(b) / a if a != 0 else 0) for a, b in zip(cutdata[-(i + 1)], cutdata[-i])] print_cuts(cuts, procs, cutdata, expanded_proc, "Cut", f, 5 if relative else 2)
def get_event_count(cls, f, proc, category, fmt, unweighed): p = cls.__plots['Events'] p.clear() p.read(f, category, Process.expand(proc), fmt=fmt) if unweighed: return p._get_histogram(proc).GetEntries() return p._get_histogram(proc).GetBinContent(1)
def cutflow(cuts, procs, relative=False, f=sys.stdout): expanded_proc = [Process.expand(proc) for proc in procs] cutdata = [[sum(float(cut[p]) for p in ps) for ps in expanded_proc] for cut in cuts] if relative: for i in xrange(1, len(cutdata)): cutdata[-i] = [float(b) / a for a, b in zip(cutdata[-(i + 1)], cutdata[-i])] namelength = max(len(unicode(cut)) for cut in cuts) fieldlengths = [] for proc, subprocs in zip(procs, expanded_proc): val = sum(cuts[0][p] for p in subprocs) length = max(len(proc), len("{:.2f}".format(float(val)))) fieldlengths.append(length) header = u"{{:{0}}}".format(namelength) \ + u"".join(u" {{:{0}}}".format(fl) for fl in fieldlengths) \ + u"\n" format = u"{{:{0}}}".format(namelength) \ + "".join(" {{:{0}.2f}}".format(fl) for fl in fieldlengths) \ + "\n" f.write(header.format("Cut", *procs)) f.write("-" * namelength + "".join(" " + "-" * fl for fl in fieldlengths) + "\n") for cut, data in zip(cuts, cutdata): f.write(format.format(cut, *data))
def cutflow(cuts, procs, relative=False, f=sys.stdout): expanded_proc = [Process.expand(proc) for proc in procs] cutdata = [[sum(float(cut[p]) for p in ps) for ps in expanded_proc] for cut in cuts] if relative: for i in xrange(1, len(cutdata)): cutdata[-i] = [ float(b) / a for a, b in zip(cutdata[-(i + 1)], cutdata[-i]) ] namelength = max(len(unicode(cut)) for cut in cuts) fieldlengths = [] for proc, subprocs in zip(procs, expanded_proc): val = sum(cuts[0][p] for p in subprocs) length = max(len(proc), len("{:.2f}".format(float(val)))) fieldlengths.append(length) header = u"{{:{0}}}".format(namelength) \ + u"".join(u" {{:{0}}}".format(fl) for fl in fieldlengths) \ + u"\n" format = u"{{:{0}}}".format(namelength) \ + "".join(" {{:{0}.2f}}".format(fl) for fl in fieldlengths) \ + "\n" f.write(header.format("Cut", *procs)) f.write("-" * namelength + "".join(" " + "-" * fl for fl in fieldlengths) + "\n") for cut, data in zip(cuts, cutdata): f.write(format.format(cut, *data))
def read_inputs(config, setup): from ttH.TauRoast.processing import Process fn = os.path.join(config.get("indir", config["outdir"]), "ntuple.root") signal = None signal_weights = None for proc, weight in sum([cfg.items() for cfg in setup['signals']], []): for p in sum([Process.expand(proc)], []): logging.debug('reading {}'.format(p)) d = rec2array(root2array(fn, str(p), setup['variables'])) if isinstance(weight, float) or isinstance(weight, int): w = np.array([weight] * len(d)) else: w = rec2array(root2array(fn, str(p), [weight])).ravel() w *= p.cross_section / p.events if signal is not None: signal = np.concatenate((signal, d)) signal_weights = np.concatenate((signal_weights, w)) else: signal = d signal_weights = w background = None background_weights = None for proc, weight in sum([cfg.items() for cfg in setup['backgrounds']], []): for p in sum([Process.expand(proc)], []): logging.debug('reading {}'.format(p)) d = rec2array(root2array(fn, str(p), setup['variables'])) if isinstance(weight, float) or isinstance(weight, int): w = np.array([weight] * len(d)) else: w = rec2array(root2array(fn, str(p), [weight])).ravel() w *= p.cross_section / p.events if background is not None: background = np.concatenate((background, d)) background_weights = np.concatenate((background_weights, w)) else: background = d background_weights = w factor = np.sum(signal_weights) / np.sum(background_weights) logging.info("renormalizing background events by factor {}".format(factor)) background_weights *= factor return signal, signal_weights, background, background_weights
def add_mva(args, config): fn = os.path.join(config["outdir"], "ntuple.root") for proc in set(sum((Process.expand(p) for p in config['plot'] + config['limits']), [])): systematics = ['NA'] if args.systematics: weights = config.get(proc.cutflow + ' weights') systematics = config.get(proc.cutflow + ' systematics', []) systematics = set([s for s, w in expand_systematics(systematics, weights)]) for unc in systematics: logging.info("using systematics: " + unc) proc.add_mva(config, fn, unc)
def analyze(args, config): fn = os.path.join(config["outdir"], "ntuple.root") if args.reuse: cutflows = split_cuts(load_cutflows(config)) else: if os.path.exists(fn): os.unlink(fn) cutflows = setup_cuts(config) for proc in set(sum((Process.expand(p) for p in config['plot'] + config['limits']), [])): uncertainties = ['NA'] if args.systematics: weights = config.get(proc.cutflow + ' weights') systematics = config.get(proc.cutflow + ' systematics', []) uncertainties = [s for s, w in expand_systematics(systematics, weights)] for unc in uncertainties: suffix = '' if unc == 'NA' else '_' + unc counts, cuts, weights = cutflows[proc.cutflow + suffix] if len(counts) > 0 and str(proc) in counts[0].processes(): continue logging.info("using systematics: " + unc) local_cuts = list(cuts) for cfg in proc.additional_cuts: local_cuts.insert(0, Cut(*cfg)) proc.analyze(config, fn, counts, local_cuts, weights, unc, args.debug_cuts) concatenated_cutflows = Cutflows() for name, (counts, cuts, weights) in cutflows.items(): cuts = counts + cuts + weights normalize(cuts, config["lumi"], config.get("event limit")) concatenated_cutflows[name] = cuts concatenated_cutflows.save(config)
def _get_histogram(self, process): procs = Process.expand(process) h = self.__hists[procs[0]].Clone() for proc in procs[1:]: h.Add(self.__hists[proc]) return h