def __init__(self, sample, **kwargs): super(Hpp3lSkimmer, self).__init__('Hpp3l', sample, **kwargs) # test if we want to run the optimization routine self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.optimize = False self.var = 'st' self.doBVeto = True self.doBScales = False self.zveto = True self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1', 'hpp2', 'hm1'] self.isSignal = 'HPlusPlusHMinus' in self.sample self.masses = [ 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ] if self.isSignal: self.masses = [ mass for mass in self.masses if 'M-{0}'.format(mass) in self.sample ] # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = { 'electrons': {}, 'muons': {}, 'taus': {}, } fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'e/tight_medium/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'm/tight_medium/fakeratePtEta') if self.tauFakeMode == 'w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) elif self.tauFakeMode == 'z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format( self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get( 'tight_medium/fakeratePtEta') for num in ['medium', 'tight']: for dlab in ['oldloose', 'newloose']: for dcut in [ 'n0p2', 'n0p1', '0p0', '0p1', '0p2', '0p3', '0p4' ]: denom = '{}_{}'.format(dlab, dcut) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom)] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEta'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM0')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM0'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM1')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM1'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM10')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM10'.format(num, denom)) self.scaleMap = { 'F': '{0}_looseScale', 'P': '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' # charge charge_path = '{0}/src/DevTools/Analyzer/data/scalefactors_charge_2016.root'.format( os.environ['CMSSW_BASE']) self.charge_rootfile = ROOT.TFile(charge_path) self.chargehists = {'electrons': {}} self.chargehists['electrons'][ 'OppositeSign'] = self.charge_rootfile.Get('OppositeSign')
def __init__(self, sample, **kwargs): # controls self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.datadriven = True self.datadrivenRegular = False self.lowmass = True self.zveto = True self.doGen = True self.doBVeto = True self.limitOnly = False self.mass = 500 self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1', 'hpp2', 'hm1'] self.channels = getChannels('Hpp3l') if self.doGen: gen = getGenChannels('Hpp3l') if 'HPlusPlusHMinusMinus' in sample: self.genChannels = gen['PP'] elif 'HPlusPlusHMinus' in sample: self.genChannels = gen['AP'] self.baseCutMap = { 'pt20': lambda row: all( [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps]), '3lmassCut': lambda row: getattr(row, '3l_mass') > 100, 'looseId': lambda row: all([ getattr( row, '{0}_passLoose{1}'.format(l, 'New' if self.new else '')) > 0.5 for l in self.leps ]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } self.lowmassCutMap = { 'pt20': lambda row: all( [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps]), 'hppVeto': lambda row: row.hpp_mass < 100, '3lmassCut': lambda row: getattr(row, '3l_mass') > 100, 'looseId': lambda row: all([ getattr( row, '{0}_passLoose{1}'.format(l, 'New' if self.new else '')) > 0.5 for l in self.leps ]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } self.zvetoCutMap = { 'pt20': lambda row: all( [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps]), '3lmassCut': lambda row: getattr(row, '3l_mass') > 100, 'looseId': lambda row: all([ getattr( row, '{0}_passLoose{1}'.format(l, 'New' if self.new else '')) > 0.5 for l in self.leps ]), 'zVeto': lambda row: abs(getattr(row, 'z_mass') - ZMASS) > 10, #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } self.selectionMap = {} self.selectionMap['default'] = lambda row: all( [self.baseCutMap[cut](row) for cut in self.baseCutMap]) if self.lowmass: self.selectionMap['lowmass'] = lambda row: all( [self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) if self.zveto: self.selectionMap['zveto'] = lambda row: all( [self.zvetoCutMap[cut](row) for cut in self.zvetoCutMap]) # sample signal plot self.cutRegions = {} masses = [ 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ] if self.limitOnly else [self.mass] for mass in masses: self.cutRegions[mass] = getSelectionMap('Hpp3l', mass) self.selectionMap['nMinusOne/massWindow/{0}/hpp0'.format( mass)] = lambda row: all([ self.cutRegions[mass][0][v](row) for v in ['st', 'zveto', 'met', 'dr'] ]) self.selectionMap['nMinusOne/massWindow/{0}/hpp1'.format( mass)] = lambda row: all([ self.cutRegions[mass][1][v](row) for v in ['st', 'zveto', 'met', 'dr'] ]) self.selectionMap['nMinusOne/massWindow/{0}/hpp2'.format( mass)] = lambda row: all([ self.cutRegions[mass][2][v](row) for v in ['st', 'zveto', 'met', 'dr'] ]) # tight loose ids to test fakerates #loose = '{}loose'.format('new' if self.new else 'old') #mva = 'tauMVA{}'.format('new' if self.new else 'old') #self.selectionMapDM = {} #self.selectionMapDM['lowmass/{}_n0p2'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))>-0.2 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_n0p1'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))>-0.1 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p0'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.0 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p1'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.1 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p2'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.2 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p3'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.3 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p4'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.4 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) self.selections = [] self.selectionHists = {} for sel in self.selectionMap: self.selections += [sel] if not self.datadriven: continue for nf in range(4): fakeChan = '{0}P{1}F'.format(3 - nf, nf) self.selections += ['{0}/{1}'.format(fakeChan, sel)] if self.datadrivenRegular: self.selections += [ '{0}_regular/{1}'.format(fakeChan, sel) ] #limitedHists = [ # 'count', # 'hpp1Pt','hpp1Eta','hpp1DecayMode', # 'hpp2Pt','hpp2Eta','hpp2DecayMode', # 'hm1Pt','hm1Eta', 'hm1DecayMode', #] #for sel in self.selectionMapDM: # self.selections += [sel] # self.selectionHists[sel] = limitedHists # for nf in range(4): # fakeChan = '{0}P{1}F'.format(3-nf,nf) # self.selections += ['{0}/{1}'.format(fakeChan,sel)] # self.selectionHists['{0}/{1}'.format(fakeChan,sel)] = limitedHists # setup histogram parameters self.histParams = { 'count': { 'x': lambda row: 1, 'xBinning': [1, 0, 2], }, # just a count of events passing selection 'numVertices': { 'x': lambda row: row.numVertices, 'xBinning': [60, 0, 60], }, 'met': { 'x': lambda row: row.met_pt, 'xBinning': [500, 0, 500], }, 'metPhi': { 'x': lambda row: row.met_phi, 'xBinning': [50, -3.14159, 3.14159], }, # h++/h-- 'hppMass': { 'x': lambda row: row.hpp_mass, 'xBinning': [1600, 0, 1600], }, 'hppPt': { 'x': lambda row: row.hpp_pt, 'xBinning': [1600, 0, 1600], }, 'hppDeltaR': { 'x': lambda row: row.hpp_deltaR, 'xBinning': [50, 0, 5], }, 'hppLeadingLeptonPt': { 'x': lambda row: row.hpp1_pt, 'xBinning': [1000, 0, 1000], }, 'hppLeadingLeptonEta': { 'x': lambda row: row.hpp1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppLeadingLeptonDecayMode': { 'x': lambda row: row.hpp1_decayMode, 'xBinning': [12, 0, 12], }, 'hppSubLeadingLeptonPt': { 'x': lambda row: row.hpp2_pt, 'xBinning': [1000, 0, 1000], }, 'hppSubLeadingLeptonEta': { 'x': lambda row: row.hpp2_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppSubLeadingLeptonDecayMode': { 'x': lambda row: row.hpp2_decayMode, 'xBinning': [12, 0, 12], }, 'hppLeadingLeptonJetCSV': { 'x': lambda row: row.hpp1jet_CSVv2, 'xBinning': [50, 0, 1], }, 'hppSubLeadingLeptonJetCSV': { 'x': lambda row: row.hpp2jet_CSVv2, 'xBinning': [50, 0, 1], }, # h-/h+ 'hmMass': { 'x': lambda row: row.hm_mt, 'xBinning': [1600, 0, 1600], }, 'hmPt': { 'x': lambda row: row.hm_pt, 'xBinning': [1600, 0, 1600], }, 'hmLeptonPt': { 'x': lambda row: row.hm1_pt, 'xBinning': [1000, 0, 1000], }, 'hmLeptonEta': { 'x': lambda row: row.hm1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hmLeptonDecayMode': { 'x': lambda row: row.hm1_decayMode, 'xBinning': [12, 0, 12], }, 'hmLeptonJetCSV': { 'x': lambda row: row.hm1jet_CSVv2, 'xBinning': [50, 0, 1], }, # best z 'zMass': { 'x': lambda row: row.z_mass, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, 'mllMinusMZ': { 'x': lambda row: abs(row.z_mass - ZMASS), 'xBinning': [100, 0, 100], 'selection': lambda row: row.z_mass > 0., }, 'zPt': { 'x': lambda row: row.z_pt, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, # w 'wMass': { 'x': lambda row: row.w_mt, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, 'wPt': { 'x': lambda row: row.w_pt, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, # event 'mass': { 'x': lambda row: getattr(row, '3l_mass'), 'xBinning': [2000, 0, 2000], }, 'st': { 'x': lambda row: row.hpp1_pt + row.hpp2_pt + row.hm1_pt, 'xBinning': [2000, 0, 2000], }, 'nJets': { 'x': lambda row: row.numJetsTight30, 'xBinning': [11, -0.5, 10.5], }, 'nBJets': { 'x': lambda row: row.numBjetsTight30, 'xBinning': [11, -0.5, 10.5], }, # for validating datadriven #'hpp1Pt' : {'x': lambda row: row.hpp1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp1Eta' : {'x': lambda row: row.hpp1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]),}, #'hpp1DecayMode' : {'x': lambda row: row.hpp1_decayMode, 'xBinning': [12, 0, 12], }, #'hpp2Pt' : {'x': lambda row: row.hpp2_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp2Eta' : {'x': lambda row: row.hpp2_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]),}, #'hpp2DecayMode' : {'x': lambda row: row.hpp2_decayMode, 'xBinning': [12, 0, 12], }, #'hm1Pt' : {'x': lambda row: row.hm1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hm1Eta' : {'x': lambda row: row.hm1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]),}, #'hm1DecayMode' : {'x': lambda row: row.hm1_decayMode, 'xBinning': [12, 0, 12], }, # 2D 'hppMass_hmMass': { 'x': lambda row: row.hpp_mass, 'y': lambda row: row.hm_mt, 'xBinning': [100, 0, 2000], 'yBinning': [100, 0, 2000], }, 'hppMass_st': { 'x': lambda row: row.hpp_mass, 'y': lambda row: row.hpp1_pt + row.hpp2_pt + row.hm1_pt, 'xBinning': [100, 0, 2000], 'yBinning': [100, 0, 2000], }, # for limits 'hppMassForLimits': { 'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True, }, } if self.limitOnly: self.histParams = { 'hppMassForLimits': { 'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True, }, } # initialize flattener super(Hpp3lFlattener, self).__init__('Hpp3l', sample, **kwargs) # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = { 'electrons': {}, 'muons': {}, 'taus': {}, } fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'e/tight_medium/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'm/tight_medium/fakeratePtEta') if self.tauFakeMode == 'w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) elif self.tauFakeMode == 'z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format( self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get( 'tight_medium/fakeratePtEta') for num in ['medium', 'tight']: for dlab in ['oldloose', 'newloose']: for dcut in [ 'n0p2', 'n0p1', '0p0', '0p1', '0p2', '0p3', '0p4' ]: denom = '{}_{}'.format(dlab, dcut) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom)] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEta'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM0')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM0'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM1')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM1'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM10')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM10'.format(num, denom)) self.scaleMap = { 'F': '{0}_looseScale', 'P': '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose'
class Hpp3lSkimmer(NtupleSkimmer): ''' Hpp3l skimmer ''' def __init__(self, sample, **kwargs): super(Hpp3lSkimmer, self).__init__('Hpp3l', sample, **kwargs) # test if we want to run the optimization routine self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.optimize = False self.var = 'st' self.doBVeto = True self.doBScales = False self.zveto = True self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1', 'hpp2', 'hm1'] self.isSignal = 'HPlusPlusHMinus' in self.sample self.masses = [ 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ] if self.isSignal: self.masses = [ mass for mass in self.masses if 'M-{0}'.format(mass) in self.sample ] # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = { 'electrons': {}, 'muons': {}, 'taus': {}, } fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'e/tight_medium/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'm/tight_medium/fakeratePtEta') if self.tauFakeMode == 'w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) elif self.tauFakeMode == 'z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format( self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get( 'tight_medium/fakeratePtEta') for num in ['medium', 'tight']: for dlab in ['oldloose', 'newloose']: for dcut in [ 'n0p2', 'n0p1', '0p0', '0p1', '0p2', '0p3', '0p4' ]: denom = '{}_{}'.format(dlab, dcut) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom)] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEta'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM0')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM0'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM1')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM1'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM10')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM10'.format(num, denom)) self.scaleMap = { 'F': '{0}_looseScale', 'P': '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' # charge charge_path = '{0}/src/DevTools/Analyzer/data/scalefactors_charge_2016.root'.format( os.environ['CMSSW_BASE']) self.charge_rootfile = ROOT.TFile(charge_path) self.chargehists = {'electrons': {}} self.chargehists['electrons'][ 'OppositeSign'] = self.charge_rootfile.Get('OppositeSign') def getFakeRate(self, lep, pt, eta, num, denom, dm=None): if lep == 'taus' and self.doDMFakes: if dm in [0, 5]: denom = denom + 'DM0' elif dm in [1, 6]: denom = denom + 'DM1' elif dm in [10]: denom = denom + 'DM10' key = self.fakekey.format(num=num, denom=denom) hist = self.fakehists[lep][key] if pt > 100.: pt = 99. b = hist.FindBin(pt, abs(eta)) return hist.GetBinContent(b), hist.GetBinError(b) def getBTagWeight(self, row): op = 1 # medium s = 'central' if self.shift == 'btagUp': s = 'up' if self.shift == 'btagDown': s = 'down' w = 1 for l in self.leps: pt = getattr(row, '{0}jet_pt'.format(l)) if not pt > 0: continue eta = getattr(row, '{0}jet_eta'.format(l)) hf = getattr(row, '{}jet_hadronFlavour'.format(l)) if hf == 5: #b flavor = 0 elif hf == 4: #c flavor = 1 else: # light flavor = 2 sf = self.btag_scales.get_sf_csv(1, pt, eta, shift=s, flavor=flavor) if getattr(row, '{0}jet_passCSVv2M'.format(l)) > 0.5: w *= 1 - sf return w def getCharge(self, lep, pt, eta): if lep == 'electrons': hist = self.chargehists['electrons']['OppositeSign'] if pt > 500: pt = 499 b = hist.FindBin(pt, abs(eta)) val, err = hist.GetBinContent(b), hist.GetBinError(b) result = val if self.shift == 'chargeUp': result = val + err if self.shift == 'chargeDown': resutl = val - err if result < 0: result = 0 return result return 1 def getWeight(self, row, doFake=False, fakeNum=None, fakeDenom=None): chanMap = { 'e': 'electrons', 'm': 'muons', 't': 'taus', } chan = ''.join([x for x in row.channel if x in 'emt']) if not fakeNum: fakeNum = 'HppMedium' if not fakeDenom: fakeDenom = 'HppLoose{0}'.format('New' if self.new else '') passID = [getattr(row, self.lepID.format(l)) for l in self.leps] if row.isData: weight = 1. else: # per event weights base = ['genWeight', 'pileupWeight', 'triggerEfficiency'] if self.shift == 'trigUp': base = ['genWeight', 'pileupWeight', 'triggerEfficiencyUp'] if self.shift == 'trigDown': base = ['genWeight', 'pileupWeight', 'triggerEfficiencyDown'] if self.shift == 'puUp': base = ['genWeight', 'pileupWeightUp', 'triggerEfficiency'] if self.shift == 'puDown': base = ['genWeight', 'pileupWeightDown', 'triggerEfficiency'] for l, lep in enumerate(self.leps): shiftString = '' if self.shift == 'lepUp': shiftString = 'Up' if self.shift == 'lepDown': shiftString = 'Down' base += [ self.scaleMap['P' if passID[l] else 'F'].format(lep) + shiftString ] vals = [getattr(row, scale) for scale in base] for scale, val in zip(base, vals): if val != val: logging.warning('{0}: {1} is NaN'.format( row.channel, scale)) weight = prod([val for val in vals if val == val]) # scale to lumi/xsec weight *= float( self.intLumi) / self.sampleLumi if self.sampleLumi else 0. if hasattr(row, 'qqZZkfactor'): weight *= row.qqZZkfactor / 1.1 # ZZ variable k factor # b tagging (veto) if self.doBScales: weight *= self.getBTagWeight(row) for l, lep in enumerate(self.leps): weight *= self.getCharge(chanMap[chan[l]], getattr(row, '{}_pt'.format(lep)), getattr(row, '{}_eta'.format(lep))) # fake scales if doFake: pts = [getattr(row, '{0}_pt'.format(x)) for x in self.leps] etas = [getattr(row, '{0}_eta'.format(x)) for x in self.leps] region = ''.join(['P' if x else 'F' for x in passID]) sign = -1 if region.count('F') % 2 == 0 and region.count( 'F') > 0 else 1 weight *= sign if not row.isData and not all(passID): weight *= -1 # subtract off MC in control for l, lep in enumerate(self.leps): if not passID[l]: # recalculate dm = None if chan[l] != 'taus' else getattr( row, '{0}_decayMode'.format(lep)) fn = fakeNum fd = fakeDenom if isinstance(fakeNum, dict): fn = fakeNum[chan[l]] if isinstance(fakeDenom, dict): fd = fakeDenom[chan[l]] fakeEff = self.getFakeRate(chanMap[chan[l]], pts[l], etas[l], fn, fd, dm=dm)[0] # read from tree #fake = self.fakeVal.format(lep) #if self.shift=='fakeUp': fake += 'Up' #if self.shift=='fakeDown': fake += 'Down' #fakeEff = getattr(row,fake) weight *= fakeEff / (1 - fakeEff) return weight def perRowAction(self, row): isData = row.isData passPt = [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps] if not all(passPt): return # all leptons pt>20 pass3l = getattr(row, '3l_mass') > 100 if not pass3l: return # m3l>100 passLooseId = all([ getattr(row, '{0}_passLoose{1}'.format( l, 'New' if self.new else '')) > 0.5 for l in self.leps ]) if not passLooseId: return if self.zveto: if abs(row.z_mass - ZMASS) < 10: return # Don't do for MC, events that pass btag contribute a factor of 1-SF passbveto = all([ getattr(row, '{0}jet_passCSVv2M'.format(l)) < 0.5 for l in self.leps ]) if self.doBScales: if isData and not passbveto and self.doBVeto: return else: if not passbveto and self.doBVeto: return # per sample cuts keep = True # currently using dy inclusive only #if self.sample=='DYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 #if self.sample=='DY1JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 #if self.sample=='DY2JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 #if self.sample=='DY3JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 #if self.sample=='DY4JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 #if self.sample=='DYJetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 #if self.sample=='DY1JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 #if self.sample=='DY2JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 #if self.sample=='DY3JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 #if self.sample=='DY4JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 if self.sample == 'WJetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 0 or row.numGenJets > 4 if self.sample == 'W1JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 1 if self.sample == 'W2JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 2 if self.sample == 'W3JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 3 if self.sample == 'W4JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 4 if not keep: return # define weights w = self.getWeight(row) wf = self.getWeight(row, doFake=True) # setup channels passID = [getattr(row, self.lepID.format(l)) for l in self.leps] region = ''.join(['P' if p else 'F' for p in passID]) nf = region.count('F') fakeChan = '{0}P{1}F'.format(3 - nf, nf) recoChan = ''.join([x for x in row.channel if x in 'emt']) recoChan = ''.join(sorted(recoChan[:2]) + sorted(recoChan[2:3])) if isData: genChan = 'all' else: genChan = row.genChannel if 'HPlusPlus' in self.sample: if 'HPlusPlusHMinusMinus' in self.sample: genChan = ''.join( sorted(genChan[:2]) + sorted(genChan[2:4])) else: genChan = ''.join( sorted(genChan[:2]) + sorted(genChan[2:3])) else: genChan = 'all' # define count regions default = True lowmass = row.hpp_mass < 100 if not isData: #genCut = all([getattr(row,'{0}_genMatch'.format(lep)) and getattr(row,'{0}_genDeltaR'.format(lep))<0.1 for lep in self.leps]) genCut = all([ (getattr(row, '{0}_genMatch'.format(lep)) and getattr(row, '{0}_genDeltaR'.format(lep)) < 0.1) or (getattr(row, '{0}_genJetMatch'.format(lep)) and getattr(row, '{0}_genJetDeltaR'.format(lep)) < 0.1) for lep in self.leps ]) genCut = True # temp to test bug # cut map v = { 'st': row.hpp1_pt + row.hpp2_pt + row.hm1_pt, 'zdiff': abs(row.z_mass - ZMASS), 'dr': row.hpp_deltaR, 'hpp': row.hpp_mass, 'met': row.met_pt, } cutRegions = {} for mass in self.masses: cutRegions[mass] = getSelectionMap('Hpp3l', mass) # optimization ranges stRange = [x * 20 for x in range(100)] zvetoRange = [x * 5 for x in range(25)] drRange = [1.5 + x * 0.1 for x in range(50)] metRange = [x * 5 for x in range(40)] # increment counts if default: if all(passID): self.increment('default', w, recoChan, genChan) if isData or genCut: self.increment(fakeChan, wf, recoChan, genChan) self.increment(fakeChan + '_regular', w, recoChan, genChan) for nTaus in range(3): for mass in self.masses: name = '{0}/hpp{1}'.format(mass, nTaus) sides = [] windows = [] sides += [cutRegions[mass][nTaus]['st'](row)] #sides += [cutRegions[mass][nTaus]['zveto'](row)] sides += [cutRegions[mass][nTaus]['met'](row)] sides += [cutRegions[mass][nTaus]['dr'](row)] windows += [cutRegions[mass][nTaus]['mass'](row)] massWindowOnly = all(windows) sideband = not all(sides) and not all(windows) massWindow = not all(sides) and all(windows) allSideband = all(sides) and not all(windows) allMassWindow = all(sides) and all(windows) if not self.optimize: if sideband: if all(passID): self.increment('new/sideband/' + name, w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/new/sideband/' + name, wf, recoChan, genChan) if massWindow: if all(passID): self.increment('new/massWindow/' + name, w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/new/massWindow/' + name, wf, recoChan, genChan) if allSideband: if all(passID): self.increment('new/allSideband/' + name, w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/new/allSideband/' + name, wf, recoChan, genChan) if allMassWindow: if all(passID): self.increment('new/allMassWindow/' + name, w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/new/allMassWindow/' + name, wf, recoChan, genChan) # run the grid of values if self.optimize: if not massWindowOnly: continue nMinusOneSt = all([ cutRegions[mass][nTaus]['zveto'](row), cutRegions[mass][nTaus]['dr'](row), cutRegions[mass][nTaus]['met'](row), cutRegions[mass][nTaus]['mass'](row) ]) nMinusOneZveto = all([ cutRegions[mass][nTaus]['st'](row), cutRegions[mass][nTaus]['dr'](row), cutRegions[mass][nTaus]['met'](row), cutRegions[mass][nTaus]['mass'](row) ]) nMinusOneDR = all([ cutRegions[mass][nTaus]['zveto'](row), cutRegions[mass][nTaus]['st'](row), cutRegions[mass][nTaus]['met'](row), cutRegions[mass][nTaus]['mass'](row) ]) nMinusOneMet = all([ cutRegions[mass][nTaus]['zveto'](row), cutRegions[mass][nTaus]['dr'](row), cutRegions[mass][nTaus]['st'](row), cutRegions[mass][nTaus]['mass'](row) ]) # 1D no cuts if self.var == 'st': for stCutVal in stRange: if v['st'] > stCutVal and nMinusOneSt: if all(passID): self.increment( 'optimize/st/{0}/{1}'.format( stCutVal, name), w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/optimize/st/{0}/{1}'.format( stCutVal, name), wf, recoChan, genChan) if self.var == 'zveto': for zvetoCutVal in zvetoRange: if v['zdiff'] > zvetoCutVal and nMinusOneZveto: if all(passID): self.increment( 'optimize/zveto/{0}/{1}'.format( zvetoCutVal, name), w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/optimize/zveto/{0}/{1}'.format( zvetoCutVal, name), wf, recoChan, genChan) if self.var == 'dr': for drCutVal in drRange: if v['dr'] < drCutVal and nMinusOneDR: if all(passID): self.increment( 'optimize/dr/{0}/{1}'.format( drCutVal, name), w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/optimize/dr/{0}/{1}'.format( drCutVal, name), wf, recoChan, genChan) if self.var == 'met': for metCutVal in metRange: if v['met'] > metCutVal and nMinusOneMet: if all(passID): self.increment( 'optimize/met/{0}/{1}'.format( metCutVal, name), w, recoChan, genChan) if isData or genCut: self.increment( fakeChan + '/optimize/met/{0}/{1}'.format( metCutVal, name), wf, recoChan, genChan) # nD #for stCutVal in stRange: # if v['st']<stCutVal: continue # for zvetoCutVal in zvetoRange: # if v['zdiff']<zvetoCutVal: continue # for drCutVal in drRange: # if v['dr']>drCutVal: continue # for metCutVal in metRange: # if v['met']<metCutVal: continue # if all(passID): self.increment('optimize/st{0}/zveto{1}/dr{2}/met{3}/{4}'.format(stCutVal,zvetoCutVal,drCutVal,metCutVal,name),w,recoChan,genChan) # if isData or genCut: self.increment(fakeChan+'optimize/st{0}/zveto{1}/dr{2}/met{3}/{4}'.format(stCutVal,zvetoCutVal,drCutVal,metCutVal,name),wf,recoChan,genChan) if lowmass: if all(passID): self.increment('lowmass', w, recoChan, genChan) if isData or genCut: self.increment(fakeChan + '/lowmass', wf, recoChan, genChan) self.increment(fakeChan + '_regular/lowmass', w, recoChan, genChan)
class Hpp3lFlattener(NtupleFlattener): ''' Hpp3l flattener ''' def __init__(self, sample, **kwargs): # controls self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.datadriven = True self.datadrivenRegular = False self.lowmass = True self.zveto = True self.doGen = True self.doBVeto = True self.limitOnly = False self.mass = 500 self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1', 'hpp2', 'hm1'] self.channels = getChannels('Hpp3l') if self.doGen: gen = getGenChannels('Hpp3l') if 'HPlusPlusHMinusMinus' in sample: self.genChannels = gen['PP'] elif 'HPlusPlusHMinus' in sample: self.genChannels = gen['AP'] self.baseCutMap = { 'pt20': lambda row: all( [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps]), '3lmassCut': lambda row: getattr(row, '3l_mass') > 100, 'looseId': lambda row: all([ getattr( row, '{0}_passLoose{1}'.format(l, 'New' if self.new else '')) > 0.5 for l in self.leps ]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } self.lowmassCutMap = { 'pt20': lambda row: all( [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps]), 'hppVeto': lambda row: row.hpp_mass < 100, '3lmassCut': lambda row: getattr(row, '3l_mass') > 100, 'looseId': lambda row: all([ getattr( row, '{0}_passLoose{1}'.format(l, 'New' if self.new else '')) > 0.5 for l in self.leps ]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } self.zvetoCutMap = { 'pt20': lambda row: all( [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps]), '3lmassCut': lambda row: getattr(row, '3l_mass') > 100, 'looseId': lambda row: all([ getattr( row, '{0}_passLoose{1}'.format(l, 'New' if self.new else '')) > 0.5 for l in self.leps ]), 'zVeto': lambda row: abs(getattr(row, 'z_mass') - ZMASS) > 10, #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } self.selectionMap = {} self.selectionMap['default'] = lambda row: all( [self.baseCutMap[cut](row) for cut in self.baseCutMap]) if self.lowmass: self.selectionMap['lowmass'] = lambda row: all( [self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) if self.zveto: self.selectionMap['zveto'] = lambda row: all( [self.zvetoCutMap[cut](row) for cut in self.zvetoCutMap]) # sample signal plot self.cutRegions = {} masses = [ 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ] if self.limitOnly else [self.mass] for mass in masses: self.cutRegions[mass] = getSelectionMap('Hpp3l', mass) self.selectionMap['nMinusOne/massWindow/{0}/hpp0'.format( mass)] = lambda row: all([ self.cutRegions[mass][0][v](row) for v in ['st', 'zveto', 'met', 'dr'] ]) self.selectionMap['nMinusOne/massWindow/{0}/hpp1'.format( mass)] = lambda row: all([ self.cutRegions[mass][1][v](row) for v in ['st', 'zveto', 'met', 'dr'] ]) self.selectionMap['nMinusOne/massWindow/{0}/hpp2'.format( mass)] = lambda row: all([ self.cutRegions[mass][2][v](row) for v in ['st', 'zveto', 'met', 'dr'] ]) # tight loose ids to test fakerates #loose = '{}loose'.format('new' if self.new else 'old') #mva = 'tauMVA{}'.format('new' if self.new else 'old') #self.selectionMapDM = {} #self.selectionMapDM['lowmass/{}_n0p2'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))>-0.2 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_n0p1'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))>-0.1 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p0'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.0 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p1'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.1 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p2'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.2 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p3'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.3 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) #self.selectionMapDM['lowmass/{}_0p4'.format(loose)] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) and all([getattr(row,'{}_{}'.format(l,mva))> 0.4 for l in self.leps if abs(getattr(row,'{}_pdgId'.format(l)))==15]) self.selections = [] self.selectionHists = {} for sel in self.selectionMap: self.selections += [sel] if not self.datadriven: continue for nf in range(4): fakeChan = '{0}P{1}F'.format(3 - nf, nf) self.selections += ['{0}/{1}'.format(fakeChan, sel)] if self.datadrivenRegular: self.selections += [ '{0}_regular/{1}'.format(fakeChan, sel) ] #limitedHists = [ # 'count', # 'hpp1Pt','hpp1Eta','hpp1DecayMode', # 'hpp2Pt','hpp2Eta','hpp2DecayMode', # 'hm1Pt','hm1Eta', 'hm1DecayMode', #] #for sel in self.selectionMapDM: # self.selections += [sel] # self.selectionHists[sel] = limitedHists # for nf in range(4): # fakeChan = '{0}P{1}F'.format(3-nf,nf) # self.selections += ['{0}/{1}'.format(fakeChan,sel)] # self.selectionHists['{0}/{1}'.format(fakeChan,sel)] = limitedHists # setup histogram parameters self.histParams = { 'count': { 'x': lambda row: 1, 'xBinning': [1, 0, 2], }, # just a count of events passing selection 'numVertices': { 'x': lambda row: row.numVertices, 'xBinning': [60, 0, 60], }, 'met': { 'x': lambda row: row.met_pt, 'xBinning': [500, 0, 500], }, 'metPhi': { 'x': lambda row: row.met_phi, 'xBinning': [50, -3.14159, 3.14159], }, # h++/h-- 'hppMass': { 'x': lambda row: row.hpp_mass, 'xBinning': [1600, 0, 1600], }, 'hppPt': { 'x': lambda row: row.hpp_pt, 'xBinning': [1600, 0, 1600], }, 'hppDeltaR': { 'x': lambda row: row.hpp_deltaR, 'xBinning': [50, 0, 5], }, 'hppLeadingLeptonPt': { 'x': lambda row: row.hpp1_pt, 'xBinning': [1000, 0, 1000], }, 'hppLeadingLeptonEta': { 'x': lambda row: row.hpp1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppLeadingLeptonDecayMode': { 'x': lambda row: row.hpp1_decayMode, 'xBinning': [12, 0, 12], }, 'hppSubLeadingLeptonPt': { 'x': lambda row: row.hpp2_pt, 'xBinning': [1000, 0, 1000], }, 'hppSubLeadingLeptonEta': { 'x': lambda row: row.hpp2_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppSubLeadingLeptonDecayMode': { 'x': lambda row: row.hpp2_decayMode, 'xBinning': [12, 0, 12], }, 'hppLeadingLeptonJetCSV': { 'x': lambda row: row.hpp1jet_CSVv2, 'xBinning': [50, 0, 1], }, 'hppSubLeadingLeptonJetCSV': { 'x': lambda row: row.hpp2jet_CSVv2, 'xBinning': [50, 0, 1], }, # h-/h+ 'hmMass': { 'x': lambda row: row.hm_mt, 'xBinning': [1600, 0, 1600], }, 'hmPt': { 'x': lambda row: row.hm_pt, 'xBinning': [1600, 0, 1600], }, 'hmLeptonPt': { 'x': lambda row: row.hm1_pt, 'xBinning': [1000, 0, 1000], }, 'hmLeptonEta': { 'x': lambda row: row.hm1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hmLeptonDecayMode': { 'x': lambda row: row.hm1_decayMode, 'xBinning': [12, 0, 12], }, 'hmLeptonJetCSV': { 'x': lambda row: row.hm1jet_CSVv2, 'xBinning': [50, 0, 1], }, # best z 'zMass': { 'x': lambda row: row.z_mass, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, 'mllMinusMZ': { 'x': lambda row: abs(row.z_mass - ZMASS), 'xBinning': [100, 0, 100], 'selection': lambda row: row.z_mass > 0., }, 'zPt': { 'x': lambda row: row.z_pt, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, # w 'wMass': { 'x': lambda row: row.w_mt, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, 'wPt': { 'x': lambda row: row.w_pt, 'xBinning': [500, 0, 500], 'selection': lambda row: row.z_mass > 0., }, # event 'mass': { 'x': lambda row: getattr(row, '3l_mass'), 'xBinning': [2000, 0, 2000], }, 'st': { 'x': lambda row: row.hpp1_pt + row.hpp2_pt + row.hm1_pt, 'xBinning': [2000, 0, 2000], }, 'nJets': { 'x': lambda row: row.numJetsTight30, 'xBinning': [11, -0.5, 10.5], }, 'nBJets': { 'x': lambda row: row.numBjetsTight30, 'xBinning': [11, -0.5, 10.5], }, # for validating datadriven #'hpp1Pt' : {'x': lambda row: row.hpp1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp1Eta' : {'x': lambda row: row.hpp1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]),}, #'hpp1DecayMode' : {'x': lambda row: row.hpp1_decayMode, 'xBinning': [12, 0, 12], }, #'hpp2Pt' : {'x': lambda row: row.hpp2_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp2Eta' : {'x': lambda row: row.hpp2_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]),}, #'hpp2DecayMode' : {'x': lambda row: row.hpp2_decayMode, 'xBinning': [12, 0, 12], }, #'hm1Pt' : {'x': lambda row: row.hm1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hm1Eta' : {'x': lambda row: row.hm1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]),}, #'hm1DecayMode' : {'x': lambda row: row.hm1_decayMode, 'xBinning': [12, 0, 12], }, # 2D 'hppMass_hmMass': { 'x': lambda row: row.hpp_mass, 'y': lambda row: row.hm_mt, 'xBinning': [100, 0, 2000], 'yBinning': [100, 0, 2000], }, 'hppMass_st': { 'x': lambda row: row.hpp_mass, 'y': lambda row: row.hpp1_pt + row.hpp2_pt + row.hm1_pt, 'xBinning': [100, 0, 2000], 'yBinning': [100, 0, 2000], }, # for limits 'hppMassForLimits': { 'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True, }, } if self.limitOnly: self.histParams = { 'hppMassForLimits': { 'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True, }, } # initialize flattener super(Hpp3lFlattener, self).__init__('Hpp3l', sample, **kwargs) # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = { 'electrons': {}, 'muons': {}, 'taus': {}, } fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'e/tight_medium/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get( 'm/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get( 'm/tight_medium/fakeratePtEta') if self.tauFakeMode == 'w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) elif self.tauFakeMode == 'z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format( os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format( self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format( num='HppMedium', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get( 'tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format( num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get( 'tight_medium/fakeratePtEta') for num in ['medium', 'tight']: for dlab in ['oldloose', 'newloose']: for dcut in [ 'n0p2', 'n0p1', '0p0', '0p1', '0p2', '0p3', '0p4' ]: denom = '{}_{}'.format(dlab, dcut) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom)] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEta'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM0')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM0'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM1')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM1'.format(num, denom)) self.fakehists['taus'][self.fakekey.format( num=num, denom=denom + 'DM10')] = self.fake_hpp_rootfile_tau.Get( '{}_{}/fakeratePtEtaDM10'.format(num, denom)) self.scaleMap = { 'F': '{0}_looseScale', 'P': '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' def getFakeRate(self, lep, pt, eta, num, denom, dm=None): if lep == 'taus' and self.doDMFakes: if dm in [0, 5]: denom = denom + 'DM0' elif dm in [1, 6]: denom = denom + 'DM1' elif dm in [10]: denom = denom + 'DM10' key = self.fakekey.format(num=num, denom=denom) hist = self.fakehists[lep][key] if pt > 100.: pt = 99. b = hist.FindBin(pt, abs(eta)) val, err = hist.GetBinContent(b), hist.GetBinError(b) #print key, pt, abs(eta), val, err return val, err def getBTagWeight(self, row): op = 1 # medium s = 'central' if self.shift == 'btagUp': s = 'up' if self.shift == 'btagDown': s = 'down' w = 1 for l in self.leps: pt = getattr(row, '{0}jet_pt'.format(l)) if not pt > 0: continue eta = getattr(row, '{0}jet_eta'.format(l)) sf = self.btag_scales.get_sf_csv(1, pt, eta, shift=s) if getattr(row, '{0}jet_passCSVv2M'.format(l)) > 0.5: w *= 1 - sf return w def getWeight(self, row, doFake=False, fakeNum=None, fakeDenom=None): if not fakeNum: fakeNum = 'HppMedium' if not fakeDenom: fakeDenom = 'HppLoose{0}'.format('New' if self.new else '') passID = [getattr(row, self.lepID.format(l)) for l in self.leps] if row.isData: weight = 1. else: # per event weights base = ['genWeight', 'pileupWeight', 'triggerEfficiency'] if self.shift == 'trigUp': base = ['genWeight', 'pileupWeight', 'triggerEfficiencyUp'] if self.shift == 'trigDown': base = ['genWeight', 'pileupWeight', 'triggerEfficiencyDown'] if self.shift == 'puUp': base = ['genWeight', 'pileupWeightUp', 'triggerEfficiency'] if self.shift == 'puDown': base = ['genWeight', 'pileupWeightDown', 'triggerEfficiency'] for l, lep in enumerate(self.leps): shiftString = '' if self.shift == 'lepUp': shiftString = 'Up' if self.shift == 'lepDown': shiftString = 'Down' base += [ self.scaleMap['P' if passID[l] else 'F'].format(lep) + shiftString ] vals = [getattr(row, scale) for scale in base] for scale, val in zip(base, vals): if val != val: logging.warning('{0}: {1} is NaN'.format( row.channel, scale)) weight = prod([val for val in vals if val == val]) # scale to lumi/xsec weight *= float( self.intLumi) / self.sampleLumi if self.sampleLumi else 0. if hasattr(row, 'qqZZkfactor'): weight *= row.qqZZkfactor / 1.1 # ZZ variable k factor # b taggin (veto) if self.doBVeto: weight *= self.getBTagWeight(row) # fake scales if doFake: chanMap = { 'e': 'electrons', 'm': 'muons', 't': 'taus', } chan = ''.join([x for x in row.channel if x in 'emt']) pts = [getattr(row, '{0}_pt'.format(x)) for x in self.leps] etas = [getattr(row, '{0}_eta'.format(x)) for x in self.leps] region = ''.join(['P' if x else 'F' for x in passID]) sign = -1 if region.count('F') % 2 == 0 and region.count( 'F') > 0 else 1 weight *= sign if not row.isData and not all(passID): weight *= -1 # subtract off MC in control for l, lep in enumerate(self.leps): if not passID[l]: # recalculate dm = None if chan[l] != 't' else getattr( row, '{0}_decayMode'.format(lep)) fn = fakeNum fd = fakeDenom if isinstance(fakeNum, dict): fn = fakeNum[chan[l]] if isinstance(fakeDenom, dict): fd = fakeDenom[chan[l]] fakeEff = self.getFakeRate(chanMap[chan[l]], pts[l], etas[l], fn, fd, dm=dm)[0] # read from tree #fake = self.fakeVal.format(lep) #if self.shift=='fakeUp': fake += 'Up' #if self.shift=='fakeDown': fake += 'Down' #fakeEff = getattr(row,fake) weight *= fakeEff / (1 - fakeEff) return weight def perRowAction(self, row): isData = row.isData passPt = [getattr(row, '{0}_pt'.format(l)) > 20 for l in self.leps] if not all(passPt): return # all leptons pt>20 # Don't do for MC, events that pass btag contribute a factor of 1-SF passbveto = all([ getattr(row, '{0}jet_passCSVv2M'.format(l)) < 0.5 for l in self.leps ]) if isData and not passbveto and self.doBVeto: return # per sample cuts keep = True if self.sample == 'DYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 0 or row.numGenJets > 4 if self.sample == 'DY1JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 1 if self.sample == 'DY2JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 2 if self.sample == 'DY3JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 3 if self.sample == 'DY4JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 4 if self.sample == 'DYJetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 0 or row.numGenJets > 4 if self.sample == 'DY1JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 1 if self.sample == 'DY2JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 2 if self.sample == 'DY3JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 3 if self.sample == 'DY4JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 4 if self.sample == 'WJetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 0 or row.numGenJets > 4 if self.sample == 'W1JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 1 if self.sample == 'W2JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 2 if self.sample == 'W3JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 3 if self.sample == 'W4JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8': keep = row.numGenJets == 4 if not keep: return # define weights w = self.getWeight(row) wf = self.getWeight(row, doFake=True) loose = '{}loose'.format('new' if self.new else 'old') wfs = {} cuts = ['n0p2', 'n0p1', '0p0', '0p1', '0p2', '0p3', '0p4'] for cut in cuts: fn = {'e': 'HppMedium', 'm': 'HppMedium', 't': 'medium'} fd = { 'e': 'HppLoose{0}'.format('New' if self.new else ''), 'm': 'HppLoose{0}'.format('New' if self.new else ''), 't': '{}_{}'.format(loose, cut) } wfs[cut] = self.getWeight(row, doFake=True, fakeNum=fn, fakeDenom=fd) # setup channels passID = [getattr(row, self.lepID.format(l)) for l in self.leps] passIDLoose = [ getattr(row, self.lepIDLoose.format(l)) for l in self.leps ] region = ''.join(['P' if p else 'F' for p in passID]) nf = region.count('F') fakeChan = '{0}P{1}F'.format(3 - nf, nf) recoChan = ''.join([x for x in row.channel if x in 'emt']) recoChan = ''.join(sorted(recoChan[:2]) + sorted(recoChan[2:3])) if isData or not self.doGen: genChan = 'all' else: genChan = row.genChannel if 'HPlusPlus' in self.sample: if 'HPlusPlusHMinusMinus' in self.sample: genChan = ''.join( sorted(genChan[:2]) + sorted(genChan[2:4])) else: genChan = ''.join( sorted(genChan[:2]) + sorted(genChan[2:3])) else: genChan = 'all' # define count regions if not isData: #genCut = all([getattr(row,'{0}_genMatch'.format(lep)) and getattr(row,'{0}_genDeltaR'.format(lep))<0.1 for lep in self.leps]) genCut = all([ (getattr(row, '{0}_genMatch'.format(lep)) and getattr(row, '{0}_genDeltaR'.format(lep)) < 0.1) or (getattr(row, '{0}_genJetMatch'.format(lep)) and getattr(row, '{0}_genJetDeltaR'.format(lep)) < 0.1) for lep in self.leps ]) # define plot regions for sel in self.selectionMap: result = self.selectionMap[sel](row) if result: if not all(passIDLoose): continue if all(passID): self.fill(row, sel, w, recoChan, genChan) if not self.datadriven: continue if isData or genCut: self.fill(row, fakeChan + '/' + sel, wf, recoChan, genChan) if self.datadrivenRegular: self.fill(row, fakeChan + '_regular/' + sel, w, recoChan, genChan)
def __init__(self,sample,**kwargs): super(Hpp3lSkimmer, self).__init__('Hpp3l',sample,**kwargs) # test if we want to run the optimization routine self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.optimize = False self.var = 'st' self.doBVeto = True self.doBScales = False self.zveto = True self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1','hpp2','hm1'] self.isSignal = 'HPlusPlusHMinus' in self.sample self.masses = [200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500] if self.isSignal: self.masses = [mass for mass in self.masses if 'M-{0}'.format(mass) in self.sample] # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = {'electrons': {}, 'muons': {}, 'taus': {},} fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight',denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight',denom='HppMedium')] = self.fake_hpp_rootfile.Get('e/tight_medium/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppTight',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppTight',denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppTight',denom='HppMedium')] = self.fake_hpp_rootfile.Get('m/tight_medium/fakeratePtEta') if self.tauFakeMode=='w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) elif self.tauFakeMode=='z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format(self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get('tight_medium/fakeratePtEta') for num in ['medium','tight']: for dlab in ['oldloose','newloose']: for dcut in ['n0p2','n0p1','0p0','0p1','0p2','0p3','0p4']: denom = '{}_{}'.format(dlab,dcut) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom)] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEta'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM0')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM0'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM1')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM1'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM10')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM10'.format(num,denom)) self.scaleMap = { 'F' : '{0}_looseScale', 'P' : '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' # charge charge_path = '{0}/src/DevTools/Analyzer/data/scalefactors_charge_2016.root'.format(os.environ['CMSSW_BASE']) self.charge_rootfile = ROOT.TFile(charge_path) self.chargehists = {'electrons': {}} self.chargehists['electrons']['OppositeSign'] = self.charge_rootfile.Get('OppositeSign')
class Hpp3lSkimmer(NtupleSkimmer): ''' Hpp3l skimmer ''' def __init__(self,sample,**kwargs): super(Hpp3lSkimmer, self).__init__('Hpp3l',sample,**kwargs) # test if we want to run the optimization routine self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.optimize = False self.var = 'st' self.doBVeto = True self.doBScales = False self.zveto = True self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1','hpp2','hm1'] self.isSignal = 'HPlusPlusHMinus' in self.sample self.masses = [200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500] if self.isSignal: self.masses = [mass for mass in self.masses if 'M-{0}'.format(mass) in self.sample] # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = {'electrons': {}, 'muons': {}, 'taus': {},} fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight',denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight',denom='HppMedium')] = self.fake_hpp_rootfile.Get('e/tight_medium/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppTight',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppTight',denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons'][self.fakekey.format(num='HppTight',denom='HppMedium')] = self.fake_hpp_rootfile.Get('m/tight_medium/fakeratePtEta') if self.tauFakeMode=='w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) elif self.tauFakeMode=='z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format(self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get('tight_medium/fakeratePtEta') for num in ['medium','tight']: for dlab in ['oldloose','newloose']: for dcut in ['n0p2','n0p1','0p0','0p1','0p2','0p3','0p4']: denom = '{}_{}'.format(dlab,dcut) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom)] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEta'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM0')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM0'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM1')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM1'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM10')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM10'.format(num,denom)) self.scaleMap = { 'F' : '{0}_looseScale', 'P' : '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' # charge charge_path = '{0}/src/DevTools/Analyzer/data/scalefactors_charge_2016.root'.format(os.environ['CMSSW_BASE']) self.charge_rootfile = ROOT.TFile(charge_path) self.chargehists = {'electrons': {}} self.chargehists['electrons']['OppositeSign'] = self.charge_rootfile.Get('OppositeSign') def getFakeRate(self,lep,pt,eta,num,denom,dm=None): if lep=='taus' and self.doDMFakes: if dm in [0,5]: denom = denom + 'DM0' elif dm in [1,6]: denom = denom + 'DM1' elif dm in [10]: denom = denom + 'DM10' key = self.fakekey.format(num=num,denom=denom) hist = self.fakehists[lep][key] if pt > 100.: pt = 99. b = hist.FindBin(pt,abs(eta)) return hist.GetBinContent(b), hist.GetBinError(b) def getBTagWeight(self,row): op = 1 # medium s = 'central' if self.shift == 'btagUp': s = 'up' if self.shift == 'btagDown': s = 'down' w = 1 for l in self.leps: pt = getattr(row,'{0}jet_pt'.format(l)) if not pt>0: continue eta = getattr(row,'{0}jet_eta'.format(l)) hf = getattr(row,'{}jet_hadronFlavour'.format(l)) if hf==5: #b flavor = 0 elif hf==4: #c flavor = 1 else: # light flavor = 2 sf = self.btag_scales.get_sf_csv(1,pt,eta,shift=s,flavor=flavor) if getattr(row,'{0}jet_passCSVv2M'.format(l))>0.5: w *= 1-sf return w def getCharge(self,lep,pt,eta): if lep=='electrons': hist = self.chargehists['electrons']['OppositeSign'] if pt > 500: pt = 499 b = hist.FindBin(pt,abs(eta)) val, err = hist.GetBinContent(b), hist.GetBinError(b) result = val if self.shift=='chargeUp': result = val + err if self.shift=='chargeDown': resutl = val - err if result < 0: result = 0 return result return 1 def getWeight(self,row,doFake=False,fakeNum=None,fakeDenom=None): chanMap = {'e': 'electrons', 'm': 'muons', 't': 'taus',} chan = ''.join([x for x in row.channel if x in 'emt']) if not fakeNum: fakeNum = 'HppMedium' if not fakeDenom: fakeDenom = 'HppLoose{0}'.format('New' if self.new else '') passID = [getattr(row,self.lepID.format(l)) for l in self.leps] if row.isData: weight = 1. else: # per event weights base = ['genWeight','pileupWeight','triggerEfficiency'] if self.shift=='trigUp': base = ['genWeight','pileupWeight','triggerEfficiencyUp'] if self.shift=='trigDown': base = ['genWeight','pileupWeight','triggerEfficiencyDown'] if self.shift=='puUp': base = ['genWeight','pileupWeightUp','triggerEfficiency'] if self.shift=='puDown': base = ['genWeight','pileupWeightDown','triggerEfficiency'] for l,lep in enumerate(self.leps): shiftString = '' if self.shift == 'lepUp': shiftString = 'Up' if self.shift == 'lepDown': shiftString = 'Down' base += [self.scaleMap['P' if passID[l] else 'F'].format(lep)+shiftString] vals = [getattr(row,scale) for scale in base] for scale,val in zip(base,vals): if val != val: logging.warning('{0}: {1} is NaN'.format(row.channel,scale)) weight = prod([val for val in vals if val==val]) # scale to lumi/xsec weight *= float(self.intLumi)/self.sampleLumi if self.sampleLumi else 0. if hasattr(row,'qqZZkfactor'): weight *= row.qqZZkfactor/1.1 # ZZ variable k factor # b tagging (veto) if self.doBScales: weight *= self.getBTagWeight(row) for l, lep in enumerate(self.leps): weight *= self.getCharge(chanMap[chan[l]], getattr(row, '{}_pt'.format(lep)), getattr(row, '{}_eta'.format(lep))) # fake scales if doFake: pts = [getattr(row,'{0}_pt'.format(x)) for x in self.leps] etas = [getattr(row,'{0}_eta'.format(x)) for x in self.leps] region = ''.join(['P' if x else 'F' for x in passID]) sign = -1 if region.count('F')%2==0 and region.count('F')>0 else 1 weight *= sign if not row.isData and not all(passID): weight *= -1 # subtract off MC in control for l,lep in enumerate(self.leps): if not passID[l]: # recalculate dm = None if chan[l]!='taus' else getattr(row,'{0}_decayMode'.format(lep)) fn = fakeNum fd = fakeDenom if isinstance(fakeNum,dict): fn = fakeNum[chan[l]] if isinstance(fakeDenom,dict): fd = fakeDenom[chan[l]] fakeEff = self.getFakeRate(chanMap[chan[l]], pts[l], etas[l], fn, fd, dm=dm)[0] # read from tree #fake = self.fakeVal.format(lep) #if self.shift=='fakeUp': fake += 'Up' #if self.shift=='fakeDown': fake += 'Down' #fakeEff = getattr(row,fake) weight *= fakeEff/(1-fakeEff) return weight def perRowAction(self,row): isData = row.isData passPt = [getattr(row,'{0}_pt'.format(l))>20 for l in self.leps] if not all(passPt): return # all leptons pt>20 pass3l = getattr(row,'3l_mass')>100 if not pass3l: return # m3l>100 passLooseId = all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]) if not passLooseId: return if self.zveto: if abs(row.z_mass-ZMASS)<10: return # Don't do for MC, events that pass btag contribute a factor of 1-SF passbveto = all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]) if self.doBScales: if isData and not passbveto and self.doBVeto: return else: if not passbveto and self.doBVeto: return # per sample cuts keep = True # currently using dy inclusive only #if self.sample=='DYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 #if self.sample=='DY1JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 #if self.sample=='DY2JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 #if self.sample=='DY3JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 #if self.sample=='DY4JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 #if self.sample=='DYJetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 #if self.sample=='DY1JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 #if self.sample=='DY2JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 #if self.sample=='DY3JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 #if self.sample=='DY4JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 if self.sample=='WJetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 if self.sample=='W1JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 if self.sample=='W2JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 if self.sample=='W3JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 if self.sample=='W4JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 if not keep: return # define weights w = self.getWeight(row) wf = self.getWeight(row,doFake=True) # setup channels passID = [getattr(row,self.lepID.format(l)) for l in self.leps] region = ''.join(['P' if p else 'F' for p in passID]) nf = region.count('F') fakeChan = '{0}P{1}F'.format(3-nf,nf) recoChan = ''.join([x for x in row.channel if x in 'emt']) recoChan = ''.join(sorted(recoChan[:2]) + sorted(recoChan[2:3])) if isData: genChan = 'all' else: genChan = row.genChannel if 'HPlusPlus' in self.sample: if 'HPlusPlusHMinusMinus' in self.sample: genChan = ''.join(sorted(genChan[:2]) + sorted(genChan[2:4])) else: genChan = ''.join(sorted(genChan[:2]) + sorted(genChan[2:3])) else: genChan = 'all' # define count regions default = True lowmass = row.hpp_mass<100 if not isData: #genCut = all([getattr(row,'{0}_genMatch'.format(lep)) and getattr(row,'{0}_genDeltaR'.format(lep))<0.1 for lep in self.leps]) genCut = all([ (getattr(row,'{0}_genMatch'.format(lep)) and getattr(row,'{0}_genDeltaR'.format(lep))<0.1) or (getattr(row,'{0}_genJetMatch'.format(lep)) and getattr(row,'{0}_genJetDeltaR'.format(lep))<0.1) for lep in self.leps ]) genCut = True # temp to test bug # cut map v = { 'st': row.hpp1_pt+row.hpp2_pt+row.hm1_pt, 'zdiff': abs(row.z_mass-ZMASS), 'dr': row.hpp_deltaR, 'hpp': row.hpp_mass, 'met': row.met_pt, } cutRegions = {} for mass in self.masses: cutRegions[mass] = getSelectionMap('Hpp3l',mass) # optimization ranges stRange = [x*20 for x in range(100)] zvetoRange = [x*5 for x in range(25)] drRange = [1.5+x*0.1 for x in range(50)] metRange = [x*5 for x in range(40)] # increment counts if default: if all(passID): self.increment('default',w,recoChan,genChan) if isData or genCut: self.increment(fakeChan,wf,recoChan,genChan) self.increment(fakeChan+'_regular',w,recoChan,genChan) for nTaus in range(3): for mass in self.masses: name = '{0}/hpp{1}'.format(mass,nTaus) sides = [] windows = [] sides += [cutRegions[mass][nTaus]['st'](row)] #sides += [cutRegions[mass][nTaus]['zveto'](row)] sides += [cutRegions[mass][nTaus]['met'](row)] sides += [cutRegions[mass][nTaus]['dr'](row)] windows += [cutRegions[mass][nTaus]['mass'](row)] massWindowOnly = all(windows) sideband = not all(sides) and not all(windows) massWindow = not all(sides) and all(windows) allSideband = all(sides) and not all(windows) allMassWindow = all(sides) and all(windows) if not self.optimize: if sideband: if all(passID): self.increment('new/sideband/'+name,w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/new/sideband/'+name,wf,recoChan,genChan) if massWindow: if all(passID): self.increment('new/massWindow/'+name,w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/new/massWindow/'+name,wf,recoChan,genChan) if allSideband: if all(passID): self.increment('new/allSideband/'+name,w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/new/allSideband/'+name,wf,recoChan,genChan) if allMassWindow: if all(passID): self.increment('new/allMassWindow/'+name,w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/new/allMassWindow/'+name,wf,recoChan,genChan) # run the grid of values if self.optimize: if not massWindowOnly: continue nMinusOneSt = all([cutRegions[mass][nTaus]['zveto'](row), cutRegions[mass][nTaus]['dr'](row), cutRegions[mass][nTaus]['met'](row), cutRegions[mass][nTaus]['mass'](row)]) nMinusOneZveto = all([cutRegions[mass][nTaus]['st'](row), cutRegions[mass][nTaus]['dr'](row), cutRegions[mass][nTaus]['met'](row), cutRegions[mass][nTaus]['mass'](row)]) nMinusOneDR = all([cutRegions[mass][nTaus]['zveto'](row), cutRegions[mass][nTaus]['st'](row), cutRegions[mass][nTaus]['met'](row), cutRegions[mass][nTaus]['mass'](row)]) nMinusOneMet = all([cutRegions[mass][nTaus]['zveto'](row), cutRegions[mass][nTaus]['dr'](row), cutRegions[mass][nTaus]['st'](row), cutRegions[mass][nTaus]['mass'](row)]) # 1D no cuts if self.var=='st': for stCutVal in stRange: if v['st']>stCutVal and nMinusOneSt: if all(passID): self.increment('optimize/st/{0}/{1}'.format(stCutVal,name),w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/optimize/st/{0}/{1}'.format(stCutVal,name),wf,recoChan,genChan) if self.var=='zveto': for zvetoCutVal in zvetoRange: if v['zdiff']>zvetoCutVal and nMinusOneZveto: if all(passID): self.increment('optimize/zveto/{0}/{1}'.format(zvetoCutVal,name),w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/optimize/zveto/{0}/{1}'.format(zvetoCutVal,name),wf,recoChan,genChan) if self.var=='dr': for drCutVal in drRange: if v['dr']<drCutVal and nMinusOneDR: if all(passID): self.increment('optimize/dr/{0}/{1}'.format(drCutVal,name),w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/optimize/dr/{0}/{1}'.format(drCutVal,name),wf,recoChan,genChan) if self.var=='met': for metCutVal in metRange: if v['met']>metCutVal and nMinusOneMet: if all(passID): self.increment('optimize/met/{0}/{1}'.format(metCutVal,name),w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/optimize/met/{0}/{1}'.format(metCutVal,name),wf,recoChan,genChan) # nD #for stCutVal in stRange: # if v['st']<stCutVal: continue # for zvetoCutVal in zvetoRange: # if v['zdiff']<zvetoCutVal: continue # for drCutVal in drRange: # if v['dr']>drCutVal: continue # for metCutVal in metRange: # if v['met']<metCutVal: continue # if all(passID): self.increment('optimize/st{0}/zveto{1}/dr{2}/met{3}/{4}'.format(stCutVal,zvetoCutVal,drCutVal,metCutVal,name),w,recoChan,genChan) # if isData or genCut: self.increment(fakeChan+'optimize/st{0}/zveto{1}/dr{2}/met{3}/{4}'.format(stCutVal,zvetoCutVal,drCutVal,metCutVal,name),wf,recoChan,genChan) if lowmass: if all(passID): self.increment('lowmass',w,recoChan,genChan) if isData or genCut: self.increment(fakeChan+'/lowmass',wf,recoChan,genChan) self.increment(fakeChan+'_regular/lowmass',w,recoChan,genChan)
def __init__(self,sample,**kwargs): # controls self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.datadriven = True self.datadrivenRegular = False self.lowmass = True self.zveto = True self.doGen = True self.limitOnly = False self.doBVeto = True self.doBScales = False self.mass = 500 self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1','hpp2','hmm1','hmm2'] self.channels = getChannels('Hpp4l') if self.doGen: gen = getGenChannels('Hpp4l') if 'HPlusPlusHMinusMinus' in sample: self.genChannels = gen['PP'] elif 'HPlusPlusHMinus' in sample: self.genChannels = gen['AP'] self.baseCutMap = { 'looseId' : lambda row: all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } if self.zveto: self.baseCutMap['zVeto'] = lambda row: abs(getattr(row,'z_mass')-ZMASS)>10 self.lowmassCutMap = { 'hppVeto' : lambda row: (row.hpp_mass<100 or row.hmm_mass<100), 'looseId' : lambda row: all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } if self.zveto: self.lowmassCutMap['zVeto'] = lambda row: abs(getattr(row,'z_mass')-ZMASS)>10 #self.zvetoCutMap = { # 'looseId' : lambda row: all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]), # 'zVeto' : lambda row: abs(getattr(row,'z_mass')-ZMASS)>10, # #'bjetveto' : lambda row: row.numBjetsTight30==0, # #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), #} self.selectionMap = {} self.selectionMap['default'] = lambda row: all([self.baseCutMap[cut](row) for cut in self.baseCutMap]) if self.lowmass: self.selectionMap['lowmass'] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) #if self.zveto: self.selectionMap['zveto'] = lambda row: all([self.zvetoCutMap[cut](row) for cut in self.zvetoCutMap]) # sample signal plot self.cutRegions = {} masses = [200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500] if self.limitOnly else [self.mass] for mass in masses: self.cutRegions[mass] = getSelectionMap('Hpp4l',mass) self.selectionMap['nMinusOne/massWindow/{0}/hpp0hmm0'.format(mass)] = lambda row: all([self.cutRegions[mass][0][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][0][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp0hmm1'.format(mass)] = lambda row: all([self.cutRegions[mass][0][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][1][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp0hmm2'.format(mass)] = lambda row: all([self.cutRegions[mass][0][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][2][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp1hmm0'.format(mass)] = lambda row: all([self.cutRegions[mass][1][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][0][v](row) for v in ['st','zveto','drmm']]) self.selectionMap['nMinusOne/massWindow/{0}/hpp1hmm1'.format(mass)] = lambda row: all([self.cutRegions[mass][1][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][1][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp1hmm2'.format(mass)] = lambda row: all([self.cutRegions[mass][1][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][2][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp2hmm0'.format(mass)] = lambda row: all([self.cutRegions[mass][2][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][0][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp2hmm1'.format(mass)] = lambda row: all([self.cutRegions[mass][2][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][1][v](row) for v in ['st','zveto','drmm']]) self.selectionMap['nMinusOne/massWindow/{0}/hpp2hmm2'.format(mass)] = lambda row: all([self.cutRegions[mass][2][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][2][v](row) for v in ['st','zveto','drmm']]) self.selections = [] self.selectionHists = {} for sel in self.selectionMap: self.selections += [sel] if not self.datadriven: continue for nf in range(5): fakeChan = '{0}P{1}F'.format(4-nf,nf) self.selections += ['{0}/{1}'.format(fakeChan,sel)] if self.datadrivenRegular: self.selections += ['{0}_regular/{1}'.format(fakeChan,sel)] # setup histogram parameters self.histParams = { 'count' : {'x': lambda row: 1, 'xBinning': [1,0,2], }, # just a count of events passing selection 'runPeriod' : {'x': lambda row: runPeriod(row), 'xBinning': [9,0,9], }, 'numVertices' : {'x': lambda row: row.numVertices, 'xBinning': [60,0,60], }, 'met' : {'x': lambda row: row.met_pt, 'xBinning': [500, 0, 500], }, 'metPhi' : {'x': lambda row: row.met_phi, 'xBinning': [50, -3.14159, 3.14159], }, # h++ 'hppMass' : {'x': lambda row: row.hpp_mass, 'xBinning': [1600, 0, 1600], }, 'hppPt' : {'x': lambda row: row.hpp_pt, 'xBinning': [1600, 0, 1600], }, 'hppDeltaR' : {'x': lambda row: row.hpp_deltaR, 'xBinning': [50, 0, 5], }, 'hppLeadingLeptonPt' : {'x': lambda row: row.hpp1_pt, 'xBinning': [200, 0, 1000], }, 'hppLeadingLeptonEta' : {'x': lambda row: row.hpp1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppSubLeadingLeptonPt' : {'x': lambda row: row.hpp2_pt, 'xBinning': [200, 0, 1000], }, 'hppSubLeadingLeptonEta' : {'x': lambda row: row.hpp2_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppLeadingLeptonJetCSV' : {'x': lambda row: row.hpp1jet_CSVv2, 'xBinning': [50, 0, 1], }, 'hppSubLeadingLeptonJetCSV' : {'x': lambda row: row.hpp2jet_CSVv2, 'xBinning': [50, 0, 1], }, # h-- 'hmmMass' : {'x': lambda row: row.hmm_mass, 'xBinning': [1600, 0, 1600], }, 'hmmPt' : {'x': lambda row: row.hmm_pt, 'xBinning': [1600, 0, 1600], }, 'hmmDeltaR' : {'x': lambda row: row.hmm_deltaR, 'xBinning': [50, 0, 5], }, 'hmmLeadingLeptonPt' : {'x': lambda row: row.hmm1_pt, 'xBinning': [200, 0, 1000], }, 'hmmLeadingLeptonEta' : {'x': lambda row: row.hmm1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hmmSubLeadingLeptonPt' : {'x': lambda row: row.hmm2_pt, 'xBinning': [200, 0, 1000], }, 'hmmSubLeadingLeptonEta' : {'x': lambda row: row.hmm2_eta, 'xBinning': [50, -2.5, 2.5], }, 'hmmLeadingLeptonJetCSV' : {'x': lambda row: row.hmm1jet_CSVv2, 'xBinning': [50, 0, 1], }, 'hmmSubLeadingLeptonJetCSV' : {'x': lambda row: row.hmm2jet_CSVv2, 'xBinning': [50, 0, 1], }, # best z 'zMass' : {'x': lambda row: row.z_mass, 'xBinning': [200, 0, 200], 'selection': lambda row: row.z_mass>0.,}, 'mllMinusMZ' : {'x': lambda row: abs(row.z_mass-ZMASS), 'xBinning': [100, 0, 100], 'selection': lambda row: row.z_mass>0.,}, 'zPt' : {'x': lambda row: row.z_pt, 'xBinning': [100, 0, 500], 'selection': lambda row: row.z_mass>0.,}, # event 'mass' : {'x': lambda row: getattr(row,'4l_mass'), 'xBinning': [200, 0, 2000], }, #'hppMassMinusHmmMass' : {'x': lambda row: row.hpp_mass-row.hmm_mass, 'xBinning': [1600, -800, 800], }, 'st' : {'x': lambda row: row.hpp1_pt+row.hpp2_pt+row.hmm1_pt+row.hmm2_pt, 'xBinning': [2000, 0, 2000],}, 'nJets' : {'x': lambda row: row.numJetsTight30, 'xBinning': [11, -0.5, 10.5], }, 'nBJets' : {'x': lambda row: row.numBjetsTight30, 'xBinning': [11, -0.5, 10.5], }, # for validating datadriven #'hpp1Pt' : {'x': lambda row: row.hpp1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp1Eta' : {'x': lambda row: row.hpp1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, #'hpp2Pt' : {'x': lambda row: row.hpp2_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp2Eta' : {'x': lambda row: row.hpp2_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, #'hmm1Pt' : {'x': lambda row: row.hmm1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hmm1Eta' : {'x': lambda row: row.hmm1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, #'hmm2Pt' : {'x': lambda row: row.hmm2_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hmm2Eta' : {'x': lambda row: row.hmm2_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, # 2D 'hppMass_hmmMass' : {'x': lambda row: row.hpp_mass, 'y': lambda row: row.hmm_mass, 'xBinning': [100, 0, 2000], 'yBinning': [50, 0, 2000],}, 'hppMass_st' : {'x': lambda row: row.hpp_mass, 'y': lambda row: row.hpp1_pt+row.hpp2_pt+row.hmm1_pt+row.hmm2_pt, 'xBinning': [100, 0, 2000], 'yBinning': [50, 0, 2000],}, # for limits 'hppMassForLimits' : {'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True,}, } if self.limitOnly: self.histParams = { 'hppMassForLimits' : {'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True,}, } # initialize flattener super(Hpp4lFlattener, self).__init__('Hpp4l',sample,**kwargs) # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = {'electrons': {}, 'muons': {}, 'taus': {},} fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get('e/tight_medium/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get('m/tight_medium/fakeratePtEta') if self.tauFakeMode=='w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) elif self.tauFakeMode=='z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format(self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get('tight_medium/fakeratePtEta') for num in ['medium','tight']: for dlab in ['oldloose','newloose']: for dcut in ['n0p2','n0p1','0p0','0p1','0p2','0p3','0p4']: denom = '{}_{}'.format(dlab,dcut) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom)] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEta'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM0')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM0'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM1')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM1'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM10')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM10'.format(num,denom)) self.scaleMap = { 'F' : '{0}_looseScale', 'P' : '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' # charge charge_path = '{0}/src/DevTools/Analyzer/data/scalefactors_charge_2016.root'.format(os.environ['CMSSW_BASE']) self.charge_rootfile = ROOT.TFile(charge_path) self.chargehists = {'electrons': {}} self.chargehists['electrons']['OppositeSign'] = self.charge_rootfile.Get('OppositeSign')
class Hpp4lFlattener(NtupleFlattener): ''' Hpp4l flattener ''' def __init__(self,sample,**kwargs): # controls self.new = True # uses NewDMs for tau loose ID self.tauFakeMode = 'z' # allowed: w, z self.doDMFakes = True self.datadriven = True self.datadrivenRegular = False self.lowmass = True self.zveto = True self.doGen = True self.limitOnly = False self.doBVeto = True self.doBScales = False self.mass = 500 self.btag_scales = BTagScales('80X') # setup properties self.leps = ['hpp1','hpp2','hmm1','hmm2'] self.channels = getChannels('Hpp4l') if self.doGen: gen = getGenChannels('Hpp4l') if 'HPlusPlusHMinusMinus' in sample: self.genChannels = gen['PP'] elif 'HPlusPlusHMinus' in sample: self.genChannels = gen['AP'] self.baseCutMap = { 'looseId' : lambda row: all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } if self.zveto: self.baseCutMap['zVeto'] = lambda row: abs(getattr(row,'z_mass')-ZMASS)>10 self.lowmassCutMap = { 'hppVeto' : lambda row: (row.hpp_mass<100 or row.hmm_mass<100), 'looseId' : lambda row: all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]), #'bjetveto' : lambda row: row.numBjetsTight30==0, #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), } if self.zveto: self.lowmassCutMap['zVeto'] = lambda row: abs(getattr(row,'z_mass')-ZMASS)>10 #self.zvetoCutMap = { # 'looseId' : lambda row: all([getattr(row,'{0}_passLoose{1}'.format(l,'New' if self.new else ''))>0.5 for l in self.leps]), # 'zVeto' : lambda row: abs(getattr(row,'z_mass')-ZMASS)>10, # #'bjetveto' : lambda row: row.numBjetsTight30==0, # #'bjetveto' : lambda row: all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]), #} self.selectionMap = {} self.selectionMap['default'] = lambda row: all([self.baseCutMap[cut](row) for cut in self.baseCutMap]) if self.lowmass: self.selectionMap['lowmass'] = lambda row: all([self.lowmassCutMap[cut](row) for cut in self.lowmassCutMap]) #if self.zveto: self.selectionMap['zveto'] = lambda row: all([self.zvetoCutMap[cut](row) for cut in self.zvetoCutMap]) # sample signal plot self.cutRegions = {} masses = [200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500] if self.limitOnly else [self.mass] for mass in masses: self.cutRegions[mass] = getSelectionMap('Hpp4l',mass) self.selectionMap['nMinusOne/massWindow/{0}/hpp0hmm0'.format(mass)] = lambda row: all([self.cutRegions[mass][0][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][0][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp0hmm1'.format(mass)] = lambda row: all([self.cutRegions[mass][0][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][1][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp0hmm2'.format(mass)] = lambda row: all([self.cutRegions[mass][0][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][2][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp1hmm0'.format(mass)] = lambda row: all([self.cutRegions[mass][1][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][0][v](row) for v in ['st','zveto','drmm']]) self.selectionMap['nMinusOne/massWindow/{0}/hpp1hmm1'.format(mass)] = lambda row: all([self.cutRegions[mass][1][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][1][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp1hmm2'.format(mass)] = lambda row: all([self.cutRegions[mass][1][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][2][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp2hmm0'.format(mass)] = lambda row: all([self.cutRegions[mass][2][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][0][v](row) for v in ['st','zveto','drmm']]) #self.selectionMap['nMinusOne/massWindow/{0}/hpp2hmm1'.format(mass)] = lambda row: all([self.cutRegions[mass][2][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][1][v](row) for v in ['st','zveto','drmm']]) self.selectionMap['nMinusOne/massWindow/{0}/hpp2hmm2'.format(mass)] = lambda row: all([self.cutRegions[mass][2][v](row) for v in ['st','zveto','drpp']]+[self.cutRegions[mass][2][v](row) for v in ['st','zveto','drmm']]) self.selections = [] self.selectionHists = {} for sel in self.selectionMap: self.selections += [sel] if not self.datadriven: continue for nf in range(5): fakeChan = '{0}P{1}F'.format(4-nf,nf) self.selections += ['{0}/{1}'.format(fakeChan,sel)] if self.datadrivenRegular: self.selections += ['{0}_regular/{1}'.format(fakeChan,sel)] # setup histogram parameters self.histParams = { 'count' : {'x': lambda row: 1, 'xBinning': [1,0,2], }, # just a count of events passing selection 'runPeriod' : {'x': lambda row: runPeriod(row), 'xBinning': [9,0,9], }, 'numVertices' : {'x': lambda row: row.numVertices, 'xBinning': [60,0,60], }, 'met' : {'x': lambda row: row.met_pt, 'xBinning': [500, 0, 500], }, 'metPhi' : {'x': lambda row: row.met_phi, 'xBinning': [50, -3.14159, 3.14159], }, # h++ 'hppMass' : {'x': lambda row: row.hpp_mass, 'xBinning': [1600, 0, 1600], }, 'hppPt' : {'x': lambda row: row.hpp_pt, 'xBinning': [1600, 0, 1600], }, 'hppDeltaR' : {'x': lambda row: row.hpp_deltaR, 'xBinning': [50, 0, 5], }, 'hppLeadingLeptonPt' : {'x': lambda row: row.hpp1_pt, 'xBinning': [200, 0, 1000], }, 'hppLeadingLeptonEta' : {'x': lambda row: row.hpp1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppSubLeadingLeptonPt' : {'x': lambda row: row.hpp2_pt, 'xBinning': [200, 0, 1000], }, 'hppSubLeadingLeptonEta' : {'x': lambda row: row.hpp2_eta, 'xBinning': [50, -2.5, 2.5], }, 'hppLeadingLeptonJetCSV' : {'x': lambda row: row.hpp1jet_CSVv2, 'xBinning': [50, 0, 1], }, 'hppSubLeadingLeptonJetCSV' : {'x': lambda row: row.hpp2jet_CSVv2, 'xBinning': [50, 0, 1], }, # h-- 'hmmMass' : {'x': lambda row: row.hmm_mass, 'xBinning': [1600, 0, 1600], }, 'hmmPt' : {'x': lambda row: row.hmm_pt, 'xBinning': [1600, 0, 1600], }, 'hmmDeltaR' : {'x': lambda row: row.hmm_deltaR, 'xBinning': [50, 0, 5], }, 'hmmLeadingLeptonPt' : {'x': lambda row: row.hmm1_pt, 'xBinning': [200, 0, 1000], }, 'hmmLeadingLeptonEta' : {'x': lambda row: row.hmm1_eta, 'xBinning': [50, -2.5, 2.5], }, 'hmmSubLeadingLeptonPt' : {'x': lambda row: row.hmm2_pt, 'xBinning': [200, 0, 1000], }, 'hmmSubLeadingLeptonEta' : {'x': lambda row: row.hmm2_eta, 'xBinning': [50, -2.5, 2.5], }, 'hmmLeadingLeptonJetCSV' : {'x': lambda row: row.hmm1jet_CSVv2, 'xBinning': [50, 0, 1], }, 'hmmSubLeadingLeptonJetCSV' : {'x': lambda row: row.hmm2jet_CSVv2, 'xBinning': [50, 0, 1], }, # best z 'zMass' : {'x': lambda row: row.z_mass, 'xBinning': [200, 0, 200], 'selection': lambda row: row.z_mass>0.,}, 'mllMinusMZ' : {'x': lambda row: abs(row.z_mass-ZMASS), 'xBinning': [100, 0, 100], 'selection': lambda row: row.z_mass>0.,}, 'zPt' : {'x': lambda row: row.z_pt, 'xBinning': [100, 0, 500], 'selection': lambda row: row.z_mass>0.,}, # event 'mass' : {'x': lambda row: getattr(row,'4l_mass'), 'xBinning': [200, 0, 2000], }, #'hppMassMinusHmmMass' : {'x': lambda row: row.hpp_mass-row.hmm_mass, 'xBinning': [1600, -800, 800], }, 'st' : {'x': lambda row: row.hpp1_pt+row.hpp2_pt+row.hmm1_pt+row.hmm2_pt, 'xBinning': [2000, 0, 2000],}, 'nJets' : {'x': lambda row: row.numJetsTight30, 'xBinning': [11, -0.5, 10.5], }, 'nBJets' : {'x': lambda row: row.numBjetsTight30, 'xBinning': [11, -0.5, 10.5], }, # for validating datadriven #'hpp1Pt' : {'x': lambda row: row.hpp1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp1Eta' : {'x': lambda row: row.hpp1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, #'hpp2Pt' : {'x': lambda row: row.hpp2_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hpp2Eta' : {'x': lambda row: row.hpp2_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, #'hmm1Pt' : {'x': lambda row: row.hmm1_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hmm1Eta' : {'x': lambda row: row.hmm1_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, #'hmm2Pt' : {'x': lambda row: row.hmm2_pt, 'xBinning': array('d', [0,20,25,30,40,50,60,100]),}, #'hmm2Eta' : {'x': lambda row: row.hmm2_eta, 'xBinning': array('d', [-2.5,-1.479,0,1.479,2.5]), }, # 2D 'hppMass_hmmMass' : {'x': lambda row: row.hpp_mass, 'y': lambda row: row.hmm_mass, 'xBinning': [100, 0, 2000], 'yBinning': [50, 0, 2000],}, 'hppMass_st' : {'x': lambda row: row.hpp_mass, 'y': lambda row: row.hpp1_pt+row.hpp2_pt+row.hmm1_pt+row.hmm2_pt, 'xBinning': [100, 0, 2000], 'yBinning': [50, 0, 2000],}, # for limits 'hppMassForLimits' : {'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True,}, } if self.limitOnly: self.histParams = { 'hppMassForLimits' : {'x': lambda row: row.hpp_mass, 'xBinning': [160, 0, 1600], 'doGen': True,}, } # initialize flattener super(Hpp4lFlattener, self).__init__('Hpp4l',sample,**kwargs) # alternative fakerates self.fakekey = '{num}_{denom}' self.fakehists = {'electrons': {}, 'muons': {}, 'taus': {},} fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_dijet_hpp_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) self.fake_hpp_rootfile = ROOT.TFile(fake_path) self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/medium_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get('e/tight_loose/fakeratePtEta') self.fakehists['electrons'][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get('e/tight_medium/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/medium_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile.Get('m/tight_loose/fakeratePtEta') self.fakehists['muons' ][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile.Get('m/tight_medium/fakeratePtEta') if self.tauFakeMode=='w': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_w_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) elif self.tauFakeMode=='z': fake_path = '{0}/src/DevTools/Analyzer/data/fakerates_z_tau_13TeV_Run2016BCDEFGH.root'.format(os.environ['CMSSW_BASE']) else: logging.error('Undefined tau fake mode {0}'.format(self.tauFakeMode)) raise self.fake_hpp_rootfile_tau = ROOT.TFile(fake_path) self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNew')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM0')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM1')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('medium_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseNewDM10')] = self.fake_hpp_rootfile_tau.Get('tight_newloose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLoose')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEta') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM0')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM0') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM1')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM1') self.fakehists['taus'][self.fakekey.format(num='HppMedium',denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('medium_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppLooseDM10')] = self.fake_hpp_rootfile_tau.Get('tight_loose/fakeratePtEtaDM10') self.fakehists['taus'][self.fakekey.format(num='HppTight', denom='HppMedium')] = self.fake_hpp_rootfile_tau.Get('tight_medium/fakeratePtEta') for num in ['medium','tight']: for dlab in ['oldloose','newloose']: for dcut in ['n0p2','n0p1','0p0','0p1','0p2','0p3','0p4']: denom = '{}_{}'.format(dlab,dcut) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom)] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEta'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM0')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM0'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM1')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM1'.format(num,denom)) self.fakehists['taus'][self.fakekey.format(num=num,denom=denom+'DM10')] = self.fake_hpp_rootfile_tau.Get('{}_{}/fakeratePtEtaDM10'.format(num,denom)) self.scaleMap = { 'F' : '{0}_looseScale', 'P' : '{0}_mediumScale', } self.fakeVal = '{0}_mediumNewFakeRate' if self.new else '{0}_mediumFakeRate' self.lepID = '{0}_passMedium' self.lepIDLoose = '{0}_passLooseNew' if self.new else '{0}_passLoose' # charge charge_path = '{0}/src/DevTools/Analyzer/data/scalefactors_charge_2016.root'.format(os.environ['CMSSW_BASE']) self.charge_rootfile = ROOT.TFile(charge_path) self.chargehists = {'electrons': {}} self.chargehists['electrons']['OppositeSign'] = self.charge_rootfile.Get('OppositeSign') def getFakeRate(self,lep,pt,eta,num,denom,dm=None): if lep=='taus' and self.doDMFakes: if dm in [0,5]: denom = denom + 'DM0' elif dm in [1,6]: denom = denom + 'DM1' elif dm in [10]: denom = denom + 'DM10' key = self.fakekey.format(num=num,denom=denom) hist = self.fakehists[lep][key] if pt > 100.: pt = 99. b = hist.FindBin(pt,abs(eta)) return hist.GetBinContent(b), hist.GetBinError(b) def getBTagWeight(self,row): op = 1 # medium s = 'central' if self.shift == 'btagUp': s = 'up' if self.shift == 'btagDown': s = 'down' w = 1 for l in self.leps: pt = getattr(row,'{0}jet_pt'.format(l)) if not pt>0: continue eta = getattr(row,'{0}jet_eta'.format(l)) hf = getattr(row,'{}jet_hadronFlavour'.format(l)) if hf==5: #b flavor = 0 elif hf==4: #c flavor = 1 else: # light flavor = 2 sf = self.btag_scales.get_sf_csv(1,pt,eta,shift=s,flavor=flavor) if getattr(row,'{0}jet_passCSVv2M'.format(l))>0.5: w *= 1-sf return w def getCharge(self,lep,pt,eta): if lep=='electrons': hist = self.chargehists['electrons']['OppositeSign'] if pt > 500: pt = 499 b = hist.FindBin(pt,abs(eta)) val, err = hist.GetBinContent(b), hist.GetBinError(b) result = val if self.shift=='chargeUp': result = val + err if self.shift=='chargeDown': resutl = val - err if result < 0: result = 0 return result return 1 def getWeight(self,row,doFake=False,fakeNum=None,fakeDenom=None): chanMap = {'e': 'electrons', 'm': 'muons', 't': 'taus',} chan = ''.join([x for x in row.channel if x in 'emt']) if not fakeNum: fakeNum = 'HppMedium' if not fakeDenom: fakeDenom = 'HppLoose{0}'.format('New' if self.new else '') passID = [getattr(row,self.lepID.format(l)) for l in self.leps] if row.isData: weight = 1. else: # per event weights base = ['genWeight','pileupWeight','triggerEfficiency'] if self.shift=='trigUp': base = ['genWeight','pileupWeight','triggerEfficiencyUp'] if self.shift=='trigDown': base = ['genWeight','pileupWeight','triggerEfficiencyDown'] if self.shift=='puUp': base = ['genWeight','pileupWeightUp','triggerEfficiency'] if self.shift=='puDown': base = ['genWeight','pileupWeightDown','triggerEfficiency'] for l,lep in enumerate(self.leps): shiftString = '' if self.shift == 'lepUp': shiftString = 'Up' if self.shift == 'lepDown': shiftString = 'Down' base += [self.scaleMap['P' if passID[l] else 'F'].format(lep)+shiftString] vals = [getattr(row,scale) for scale in base] for scale,val in zip(base,vals): if val != val: logging.warning('{0}: {1} is NaN'.format(row.channel,scale)) weight = prod([val for val in vals if val==val]) # scale to lumi/xsec weight *= float(self.intLumi)/self.sampleLumi if self.sampleLumi else 0. if hasattr(row,'qqZZkfactor'): weight *= row.qqZZkfactor/1.1 # ZZ variable k factor # b tagging (veto) if self.doBScales: weight *= self.getBTagWeight(row) for l, lep in enumerate(self.leps): weight *= self.getCharge(chanMap[chan[l]], getattr(row, '{}_pt'.format(lep)), getattr(row, '{}_eta'.format(lep))) # fake scales if doFake: pts = [getattr(row,'{0}_pt'.format(x)) for x in self.leps] etas = [getattr(row,'{0}_eta'.format(x)) for x in self.leps] region = ''.join(['P' if x else 'F' for x in passID]) sign = -1 if region.count('F')%2==0 and region.count('F')>0 else 1 weight *= sign if not row.isData and not all(passID): weight *= -1 # subtract off MC in control for l,lep in enumerate(self.leps): if not passID[l]: # recalculate dm = None if chan[l]!='t' else getattr(row,'{0}_decayMode'.format(lep)) fakeEff = self.getFakeRate(chanMap[chan[l]], pts[l], etas[l], fakeNum, fakeDenom, dm=dm)[0] # read from tree #fake = self.fakeVal.format(lep) #if self.shift=='fakeUp': fake += 'Up' #if self.shift=='fakeDown': fake += 'Down' #fakeEff = getattr(row,fake) weight *= fakeEff/(1-fakeEff) return weight def perRowAction(self,row): isData = row.isData # Don't do for MC, events that pass btag contribute a factor of 1-SF passbveto = all([getattr(row,'{0}jet_passCSVv2M'.format(l))<0.5 for l in self.leps]) if self.doBScales: if isData and not passbveto and self.doBVeto: return else: if not passbveto and self.doBVeto: return # per sample cuts keep = True # currently using dy inclusive only #if self.sample=='DYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 #if self.sample=='DY1JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 #if self.sample=='DY2JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 #if self.sample=='DY3JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 #if self.sample=='DY4JetsToLL_M-10to50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 #if self.sample=='DYJetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 #if self.sample=='DY1JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 #if self.sample=='DY2JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 #if self.sample=='DY3JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 #if self.sample=='DY4JetsToLL_M-50_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 if self.sample=='WJetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==0 or row.numGenJets>4 if self.sample=='W1JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==1 if self.sample=='W2JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==2 if self.sample=='W3JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==3 if self.sample=='W4JetsToLNu_TuneCUETP8M1_13TeV-madgraphMLM-pythia8' : keep = row.numGenJets==4 if not keep: return # define weights w = self.getWeight(row) wf = self.getWeight(row,doFake=True) # setup channels passID = [getattr(row,self.lepID.format(l)) for l in self.leps] passIDLoose = [getattr(row,self.lepIDLoose.format(l)) for l in self.leps] region = ''.join(['P' if p else 'F' for p in passID]) nf = region.count('F') fakeChan = '{0}P{1}F'.format(4-nf,nf) recoChan = ''.join([x for x in row.channel if x in 'emt']) recoChan = ''.join(sorted(recoChan[:2]) + sorted(recoChan[2:4])) if isData or not self.doGen: genChan = 'all' else: genChan = row.genChannel if 'HPlusPlus' in self.sample: if 'HPlusPlusHMinusMinus' in self.sample: genChan = ''.join(sorted(genChan[:2]) + sorted(genChan[2:4])) else: genChan = ''.join(sorted(genChan[:2]) + sorted(genChan[2:3])) else: genChan = 'all' # define count regions if not isData: #genCut = all([getattr(row,'{0}_genMatch'.format(lep)) and getattr(row,'{0}_genDeltaR'.format(lep))<0.1 for lep in self.leps]) genCut = all([ (getattr(row,'{0}_genMatch'.format(lep)) and getattr(row,'{0}_genDeltaR'.format(lep))<0.1) or (getattr(row,'{0}_genJetMatch'.format(lep)) and getattr(row,'{0}_genJetDeltaR'.format(lep))<0.1) for lep in self.leps ]) genCut = True # temp to test bug # define plot regions for sel in self.selectionMap: result = self.selectionMap[sel](row) if result: if not all(passIDLoose): continue if all(passID): self.fill(row,sel,w,recoChan,genChan) if not self.datadriven: continue if isData or genCut: self.fill(row,fakeChan+'/'+sel,wf,recoChan,genChan) if self.datadrivenRegular:self.fill(row,fakeChan+'_regular/'+sel,w,recoChan,genChan)