# Author: Izaak Neutelings (May 2020) import os import getpass, platform import importlib from fnmatch import fnmatch from TauFW.PicoProducer import basedir from TauFW.common.tools.log import Logger from TauFW.common.tools.file import ensurefile from TauFW.common.tools.utils import repkey, isglob LOG = Logger('Storage') host = platform.node() def getsedir(): """Guess the storage element path for a given user and host.""" user = getpass.getuser() sedir = "" if 'lxplus' in host: sedir = "/eos/user/%s/%s/"%(user[0],user) elif "t3" in host and "psi.ch" in host: sedir = "/pnfs/psi.ch/cms/trivcat/store/user/%s/"%(user) elif "etp" in host: sedir = "/store/user/{}/".format(user) return sedir def gettmpdirs(): """Guess the temporary directory for a given user and host.""" user = getpass.getuser() tmphadddir = "/tmp/%s/"%(user) # temporary dir for creating intermediate hadd files tmpskimdir = "" # temporary dir for creating skimmed file before copying to outdir
# Author: Izaak Neutelings (May 2020) import os, sys from math import sqrt, sin, cos, pi from itertools import combinations from ROOT import TH1D, TLorentzVector from TauFW.PicoProducer import basedir from TauFW.common.tools.utils import convertstr # for picojob.py from TauFW.common.tools.file import ensurefile from TauFW.common.tools.file import ensuremodule as _ensuremodule from TauFW.common.tools.log import Logger from PhysicsTools.NanoAODTools.postprocessing.framework.datamodel import Collection, Event LOG = Logger('Analysis') def ensuremodule(modname): """Check if module exists and has class of same name.""" return _ensuremodule(modname, "PicoProducer.analysis") def getmodule(modname): """Get give module from python module in python/analysis of the same name.""" module = ensuremodule(modname) modclass = modname.split('.')[-1] return getattr(module, modclass) def ensurebranches(tree, branches): """Check if these branches are available in the tree branch list, if not, redirect them.""" if tree.GetEntries() < 1: print "WARNING! Empty tree!"
#! /usr/bin/env python # Author: Izaak Neutelings (April 2020) import os import TauFW.PicoProducer.tools.config as GLOB from TauFW.common.tools.utils import execute from TauFW.common.tools.log import Logger, bold from TauFW.PicoProducer.analysis.utils import ensuremodule from TauFW.PicoProducer.storage.utils import getsamples, print_no_samples os.chdir(GLOB.basedir) CONFIG = GLOB.getconfig(verb=0) LOG = Logger() ########### # RUN # ########### def main_run(args): """Run given module locally.""" if args.verbosity >= 1: print ">>> main_run", args eras = args.eras # eras to loop over and run channels = args.channels # channels to loop over and run tag = args.tag # extra tag for output file outdir = args.outdir # output directory dtypes = args.dtypes # filter (only include) these sample types ('data','mc','embed') filters = args.samples # filter (only include) these samples (glob patterns) dasfilters = args.dasfilters # filter (only include) these das paths (glob patterns) vetoes = args.vetoes # exclude these sample (glob patterns) dasvetoes = args.dasvetoes # exclude these DAS paths (glob patterns) extraopts = args.extraopts # extra options for module (for all runs)
# -*- coding: utf-8 -*- # Author: Izaak Neutelings (June 2020) import os from math import sqrt, log10, ceil, floor from TauFW.common.tools.file import ensuredir, ensureTFile from TauFW.common.tools.utils import isnumber, islist, ensurelist, unwraplistargs from TauFW.common.tools.log import Logger from TauFW.Plotter.plot import moddir import TauFW.Plotter.plot.CMSStyle as CMSStyle import ROOT ROOT.PyConfig.IgnoreCommandLineOptions = True from ROOT import gDirectory, gROOT, TH1, THStack, TGraphErrors, TGraphAsymmErrors, Double,\ kSolid, kDashed, kDotted, kBlack, kWhite #moddir = os.path.dirname(__file__) gROOT.SetBatch(True) LOG = Logger('Plot') def frange(start, end, step): """Return a list of numbers between start and end, for a given stepsize.""" flist = [start] next = start + step while next < end: flist.append(next) next += step return flist def magnitude(x): """Get magnitude of a number. E.g. 45 is 2, 2304 is 4, 0.84 is -1""" if x == 0: return 0
#! /usr/bin/env python # Author: Izaak Neutelings (May 2020) import os, sys, re, glob, json from datetime import datetime import importlib import getpass, platform from collections import OrderedDict from TauFW.PicoProducer import basedir from TauFW.common.tools.file import ensuredir, ensurefile from TauFW.common.tools.log import Logger, color, bold, header from TauFW.PicoProducer.storage.utils import getsedir, gettmpdirs # DEFAULTS LOG = Logger('GLOB') CONFIG = None user = getpass.getuser() host = platform.node() #basedir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) dtypes = ['mc', 'data', 'embed'] _eras = OrderedDict([('2016', 'samples_2016.py'), ('2017', 'samples_2017.py'), ('2018', 'samples_2018.py')]) _channels = OrderedDict([('skim', 'skimjob.py'), ('test', 'test.py'), ('mutau', 'ModuleMuTauSimple')]) _sedir = getsedir() # guess storage element on current host _tmpskimdir, _tmphadddir = gettmpdirs( ) # _tmphadddir: temporary dir for creating intermediate hadd files # _tmpskimdir: temporary dir for creating skimmed file before copying to outdir _jobdir = "output/$ERA/$CHANNEL/$SAMPLE" # for job config and log files _outdir = _tmphadddir + _jobdir # for job output _picodir = _sedir + "analysis/$ERA/$GROUP" # for storage of analysis ("pico") tuples after hadd _nanodir = _sedir + "samples/nano/$ERA/$DAS" # for storage of (skimmed) nanoAOD
# -*- coding: utf-8 -*- # Author: Izaak Neutelings (June 2020) import re, glob from TauFW.common.tools.utils import isnumber, islist, ensurelist, unwraplistargs, quotestrs, repkey, getyear from TauFW.common.tools.file import ensuredir, ensureTFile, ensuremodule from TauFW.common.tools.log import Logger, color from TauFW.Plotter.plot.Variable import Variable, Var, ensurevar from TauFW.Plotter.plot.Selection import Selection, Sel import TauFW.Plotter.plot.CMSStyle as CMSStyle import ROOT ROOT.PyConfig.IgnoreCommandLineOptions = True from ROOT import gDirectory, gROOT, TH1, THStack, kDotted, kBlack, kWhite gROOT.SetBatch(True) LOG = Logger('Sample') era = None # data period: 2016, 2017, 2018, ... lumi = -1 # integrated luminosity [fb-1] cme = 13 # center-of-mass energy [TeV] lumi_dict = { '7': 5.1, '2016': 35.9, '8': 19.7, '2017': 41.5, '2012': 19.7, '2018': 59.7, 'Run2': 137.1, 'Phase2': 3000, } xsecs_nlo = { # NLO cross sections to compute k-factor for stitching 'DYJetsToLL_M-50': 3*2025.74, 'DYJetsToLL_M-10to50': 18610.0, 'WJetsToLNu': 61526.7,
# Author: Izaak Neutelings (November 2018) import os, re from TauFW.common.tools.file import ensureTFile from TauFW.common.tools.log import Logger LOG = Logger('ScaleFactorTool') class ScaleFactor: def __init__(self, filename, histname, name="<noname>", ptvseta=True, verb=0): #print '>>> ScaleFactor.init("%s","%s",name="%s",ptvseta=%r)'%(filename,histname,name,ptvseta) self.name = name self.ptvseta = ptvseta self.filename = filename LOG.verb("ScaleFactor(%s): Opening %s:%r..."%(self.name,filename,histname),verb,1) self.file = ensureTFile(filename) self.hist = self.file.Get(histname) LOG.insist(self.hist,"ScaleFactor(%s): histogram %r does not exist in %s"%(self.name,histname,filename)) self.hist.SetDirectory(0) self.file.Close() if ptvseta: self.getSF = self.getSF_ptvseta else: self.getSF = self.getSF_etavspt def __mul__(self, oScaleFactor): return ScaleFactorProduct(self, oScaleFactor) def getSF_ptvseta(self, pt, eta): """Get SF for a given pT, eta.""" xbin = self.hist.GetXaxis().FindBin(eta) ybin = self.hist.GetYaxis().FindBin(pt)
# Author: Sebastian Brommer (October 2020) import os, re from TauFW.common.tools.file import ensureTFile from TauFW.common.tools.log import Logger LOG = Logger('RooWorkspaceTool') class RooScaleFactor: """ Main class for reading out functions from RooWorkspace """ def __init__(self, workspace, function, arguments): self.workspace_file = ensureTFile(workspace) self.arguments = arguments self.workspace = self.workspace_file.Get("w") self.function = self.workspace.function(function) self.argset = self.workspace.argSet(",".join(self.arguments)) def getSF(self, parameters): """ Calculate the SF and return the value First set the RealValue according to the given paramters dict and than return the value of the Workspace function The dict contains the argument name and the value e.g.: { 'm_pt' : pt, 'm_eta': abs(eta) } """ for para in self.arguments:
# Author: Izaak Neutelings (November 2018) import os, re from TauFW.PicoProducer import datadir from TauFW.common.tools.file import ensureTFile from TauFW.common.tools.log import Logger datadir = os.path.join(datadir, "pileup") LOG = Logger('PileupTool', showname=True) class PileupWeightTool: def __init__(self, era, sigma='central', sample=None, buggy=False, flat=False, verb=0): """Load data and MC pilup profiles.""" assert ( sigma in ['central', 'up', 'down'] ), "You must choose a s.d. variation from: 'central', 'up', or 'down'." minbias = '69p2' if sigma == 'down': minbias = '66p0168' # -4.6% elif sigma == 'up': minbias = '72p3832' # +4.6% if era == '2016': datafilename = os.path.join( datadir, "Data_PileUp_%s_%s.root" % (era, minbias))
#! /usr/bin/env python # Author: Izaak Neutelings (December 2018) import time start0 = time.time() print print ">>> importing modules..." from TauFW.common.tools.log import Logger LOG = Logger("testSF") start1 = time.time() from ROOT import TFile print ">>> imported ROOT classes after %.1f seconds" % (time.time() - start1) start1 = time.time() from TauFW.PicoProducer.corrections.ScaleFactorTool import * print ">>> imported ScaleFactorTool classes after %.1f seconds" % ( time.time() - start1) start1 = time.time() from TauFW.PicoProducer.corrections.MuonSFs import * print ">>> imported MuonSFs classes after %.1f seconds" % (time.time() - start1) start1 = time.time() from TauFW.PicoProducer.corrections.ElectronSFs import * print ">>> imported ElectronSFs classes after %.1f seconds" % (time.time() - start1) start1 = time.time() from TauFW.PicoProducer.corrections.TauTriggerSFs import * print ">>> imported TauTriggerSFs classes after %.1f seconds" % (
# https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X # nanoAOD-tools/python/postprocessing/modules/btv/btagSFProducer.py # https://github.com/cms-nanoAOD/nanoAOD-tools/blob/master/python/postprocessing/modules/btv/btagSFProducer.py import os from array import array import ROOT #ROOT.gROOT.ProcessLine('.L ./BTagCalibrationStandalone.cpp+') from TauFW.PicoProducer import datadir from TauFW.common.tools.file import ensureTFile from TauFW.common.tools.log import Logger from ROOT import TH2F, BTagCalibration, BTagCalibrationReader from ROOT.BTagEntry import OP_LOOSE, OP_MEDIUM, OP_TIGHT, OP_RESHAPING from ROOT.BTagEntry import FLAV_B, FLAV_C, FLAV_UDSG datadir = os.path.join(datadir,"btag") LOG = Logger('BTagTool',showname=True) class BTagWPs: """Contain b tagging working points.""" def __init__( self, tagger, year=2017 ): assert( year in [2016,2017,2018] ), "You must choose a year from: 2016, 2017, or 2018." if year==2016: if 'deep' in tagger.lower(): self.loose = 0.2217 # 0.2219 for 2016ReReco vs. 2016Legacy self.medium = 0.6321 # 0.6324 self.tight = 0.8953 # 0.8958 else: self.loose = 0.5426 # for 80X ReReco self.medium = 0.8484 self.tight = 0.9535