00001 import FWCore.ParameterSet.Config as cms
00002 import Validation.RecoTau.ValidationUtils as Utils
00003 import copy
00004 import re
00005 import os
00006
00007
00008
00009
00010 """
00011
00012 RecoTauValidation_cfi.py
00013
00014 Contains the standard tau Validation parameters. It is organized into
00015 the following sections.
00016
00017 DENOMINATOR
00018
00019 Set common kinematic cuts (pt > 5 and eta < 2.5) on the denominator source.
00020 Note that the denominator depends on the type of test (signal/background/e etc)
00021
00022 The denominator kinematic cutter requires that
00023
00024 HISTOGRAMS
00025
00026 Produce numerator and denominator histgorams used to produce
00027 tau efficiency plots
00028
00029 Provides sequence:
00030 TauValNumeratorAndDenominator
00031 Requires:
00032 tauValSelectedDenominator (filtered GenJet collection)
00033
00034 EFFICIENCY
00035
00036 Using numerator and denominators, calculate and store
00037 the efficiency curves
00038
00039 Provides sequence:
00040 TauEfficiencies
00041 Requires:
00042 TauValNumeratorAndDenominator
00043
00044 PLOTTING
00045
00046 Plot curves calculated in efficiency, in both an overlay mode
00047 showing overall performance for a release, and the indvidual
00048 discriminator efficiency compared to a given release
00049
00050 Provides sequence:
00051 loadTau
00052 plotTauValidation
00053 loadAndPlotTauValidation
00054
00055 Requires:
00056 TauEfficiencies, external root file to compare to
00057
00058 Plotting must be executed in a separate cmsRun job!
00059
00060 UTILITIES
00061
00062 Various scripts to automate things...
00063
00064
00065 """
00066
00067 """
00068
00069 DENOMINATOR
00070
00071 """
00072
00073 kinematicSelectedTauValDenominatorCut = cms.string('pt > 5. && abs(eta) < 2.5')
00074 denominator = cms.InputTag("kinematicSelectedTauValDenominator")
00075
00076 """
00077
00078 HISTOGRAMS
00079
00080 Plot the pt/eta/energy/phi spectrum of PFTaus that pass
00081 a series of PFTauDiscriminator cuts.
00082
00083 These will be used as the numerator/denominators of the
00084 efficiency calculations
00085 """
00086
00087
00088 proc = cms.Process('helper')
00089
00090 StandardMatchingParameters = cms.PSet(
00091 DataType = cms.string('Leptons'),
00092 MatchDeltaR_Leptons = cms.double(0.15),
00093 MatchDeltaR_Jets = cms.double(0.3),
00094 SaveOutputHistograms = cms.bool(False),
00095
00096 RefCollection = denominator,
00097 TauPtCut = cms.double(0.),
00098 recoCuts = cms.string(''),
00099 genCuts = cms.string(''),
00100 chainCuts = cms.bool(False)
00101 )
00102
00103 GenericTriggerSelectionParameters = cms.PSet(
00104 andOr = cms.bool( False ),
00105 dbLabel = cms.string("PFTauDQMTrigger"),
00106 andOrHlt = cms.bool(True),
00107 hltInputTag = cms.InputTag("TriggerResults::HLT"),
00108
00109 hltPaths = cms.vstring('HLT_IsoMu*_eta*_LooseIsoPFTau*_v*','HLT_DoubleIsoPFTau*_Trk*_eta*_v*'),
00110 errorReplyHlt = cms.bool(False),
00111 verbosityLevel = cms.uint32(0)
00112 )
00113
00114 proc.templateAnalyzer = cms.EDAnalyzer(
00115 "TauTagValidation",
00116 StandardMatchingParameters,
00117 GenericTriggerSelection = GenericTriggerSelectionParameters,
00118 ExtensionName = cms.string(""),
00119 TauProducer = cms.InputTag(''),
00120 discriminators = cms.VPSet(
00121 )
00122 )
00123
00124 proc.RunHPSValidation = proc.templateAnalyzer.clone()
00125 proc.RunHPSValidation.ExtensionName = ""
00126
00127 proc.RunHPSValidation.TauProducer = cms.InputTag('hpsPFTauProducer')
00128 proc.RunHPSValidation.discriminators = cms.VPSet(
00129 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByDecayModeFinding"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00130 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByVLooseChargedIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00131 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseChargedIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00132 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightChargedIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00133 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00134 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByVLooseCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00135 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00136 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMediumCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00137 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00138 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00139 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMediumElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00140 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00141 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseMuonRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00142 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMediumMuonRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00143 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightMuonRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00144 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMVAElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00145 )
00146
00147 proc.TauValNumeratorAndDenominator = cms.Sequence(
00148 proc.RunHPSValidation
00149 )
00150
00151 """
00152
00153 EFFICIENCY
00154
00155 Tau efficiency calculations
00156
00157 Define the Efficiency curves to produce. Each
00158 efficiency producer takes the numberator and denominator
00159 histograms and the dependent variables.
00160 """
00161
00162 plotPset = Utils.SetPlotSequence(proc.TauValNumeratorAndDenominator)
00163 proc.efficiencies = cms.EDAnalyzer(
00164 "TauDQMHistEffProducer",
00165 plots = plotPset
00166 )
00167
00168
00169
00170
00171
00172
00173
00174
00175 proc.normalizePlots = cms.EDAnalyzer(
00176 "DQMHistNormalizer",
00177 plotNamesToNormalize = cms.vstring('*_pTRatio_*','*_Size_*','*_SumPt_*','*_dRTauRefJet*'),
00178 reference = cms.string('*_pTRatio_allHadronic')
00179 )
00180
00181 proc.TauEfficiencies = cms.Sequence(
00182 proc.efficiencies*
00183 proc.normalizePlots
00184 )
00185
00186 """
00187
00188 PLOTTING
00189
00190 loadTau: load two separate TauVal root files into the DQM
00191 so the plotter can access them
00192
00193 """
00194
00195 loadTau = cms.EDAnalyzer("TauDQMFileLoader",
00196 test = cms.PSet(
00197
00198 inputFileNames = cms.vstring('/opt/sbg/cms/ui4_data1/dbodin/CMSSW_3_5_1/src/TauID/QCD_recoFiles/TauVal_CMSSW_3_6_0_QCD.root'),
00199 scaleFactor = cms.double(1.),
00200 dqmDirectory_store = cms.string('test')
00201 ),
00202 reference = cms.PSet(
00203 inputFileNames = cms.vstring('/opt/sbg/cms/ui4_data1/dbodin/CMSSW_3_5_1/src/TauID/QCD_recoFiles/TauVal_CMSSW_3_6_0_QCD.root'),
00204 scaleFactor = cms.double(1.),
00205 dqmDirectory_store = cms.string('reference')
00206 )
00207 )
00208
00209
00210
00211
00212 xAxisStuff = cms.PSet(
00213 xAxisTitle = cms.string('P_{T} / GeV'),
00214 xAxisTitleOffset = cms.double(0.9),
00215 xAxisTitleSize = cms.double(0.05)
00216 )
00217 xModifiers = [['pt',['xAxisTitle'],['P_{T} / GeV']],['eta',['xAxisTitle'],['#eta']],['phi',['xAxisTitle'],['#phi']],['pileup',['xAxisTitle'],['# of Reco Vertices']]]
00218
00219 yAxisStuff =cms.PSet(
00220 yScale = cms.string('linear'),
00221 minY_linear = cms.double(0.),
00222 maxY_linear = cms.double(1.6),
00223 minY_log = cms.double(0.001),
00224 maxY_log = cms.double(1.8),
00225 yAxisTitle = cms.string('#varepsilon'),
00226 yAxisTitleOffset = cms.double(1.1),
00227 yAxisTitleSize = cms.double(0.05)
00228 )
00229 yModifiers = [['efficiency',['yScale','yAxisTitle'],['linear','#varepsilon']],['fakeRate',['yScale','yAxisTitle'],['log','Fake rate']]]
00230
00231 legStuff = cms.PSet(
00232 posX = cms.double(0.50),
00233 posY = cms.double(0.72),
00234 sizeX = cms.double(0.39),
00235 sizeY = cms.double(0.17),
00236 header = cms.string(''),
00237 option = cms.string('brNDC'),
00238 borderSize = cms.int32(0),
00239 fillColor = cms.int32(0)
00240 )
00241 legModifiers = [['efficiency',['posY','sizeY'],[0.72,0.17]],['efficiency_overlay',['posY','sizeY'],[0.66,0.23]]]
00242
00243 drawOptStuff = cms.PSet(
00244 markerColor = cms.int32(1),
00245 markerSize = cms.double(1.),
00246 markerStyle = cms.int32(20),
00247 lineColor = cms.int32(1),
00248 lineStyle = cms.int32(1),
00249 lineWidth = cms.int32(2),
00250 drawOption = cms.string('ex0'),
00251 drawOptionLegend = cms.string('p')
00252 )
00253 drawOptModifiers = [['eff_overlay01',['markerColor','lineColor'],[1,1]],['eff_overlay02',['markerColor','lineColor'],[2,2]],['eff_overlay03',['markerColor','lineColor'],[3,3]],['eff_overlay04',['markerColor','lineColor'],[4,4]],['eff_overlay05',['markerColor','lineColor'],[6,6]],['eff_overlay06',['markerColor','lineColor'],[5,5]],['eff_overlay07',['markerColor','lineColor'],[7,7]],['eff_overlay08',['markerColor','lineColor'],[28,28]],['eff_overlay09',['markerColor','lineColor','markerStyle'],[2,2,29]],['eff_overlay010',['markerColor','lineColor','markerStyle'],[4,4,29]],['eff_overlay011',['markerColor','lineColor','markerStyle'],[6,6,29]]]
00254
00255 standardDrawingStuff = cms.PSet(
00256 canvasSizeX = cms.int32(640),
00257 canvasSizeY = cms.int32(640),
00258 indOutputFileName = cms.string('#PLOT#.png'),
00259 xAxes = Utils.SpawnPSet(xModifiers,xAxisStuff),
00260 yAxes = Utils.SpawnPSet(yModifiers,yAxisStuff),
00261 legends = Utils.SpawnPSet(legModifiers,legStuff),
00262 labels = cms.PSet(
00263 pt = cms.PSet(
00264 posX = cms.double(0.19),
00265 posY = cms.double(0.77),
00266 sizeX = cms.double(0.12),
00267 sizeY = cms.double(0.04),
00268 option = cms.string('brNDC'),
00269 borderSize = cms.int32(0),
00270 fillColor = cms.int32(0),
00271 textColor = cms.int32(1),
00272 textSize = cms.double(0.04),
00273 textAlign = cms.int32(22),
00274 text = cms.vstring('P_{T} > 5 GeV')
00275 ),
00276 eta = cms.PSet(
00277 posX = cms.double(0.19),
00278 posY = cms.double(0.83),
00279 sizeX = cms.double(0.12),
00280 sizeY = cms.double(0.04),
00281 option = cms.string('brNDC'),
00282 borderSize = cms.int32(0),
00283 fillColor = cms.int32(0),
00284 textColor = cms.int32(1),
00285 textSize = cms.double(0.04),
00286 textAlign = cms.int32(22),
00287 text = cms.vstring('-2.5 < #eta < +2.5')
00288 )
00289 ),
00290 drawOptionSets = cms.PSet(
00291 efficiency = cms.PSet(
00292 test = cms.PSet(
00293 markerColor = cms.int32(4),
00294 markerSize = cms.double(1.),
00295 markerStyle = cms.int32(20),
00296 lineColor = cms.int32(1),
00297 lineStyle = cms.int32(1),
00298 lineWidth = cms.int32(1),
00299 drawOption = cms.string('ep'),
00300 drawOptionLegend = cms.string('p')
00301 ),
00302 reference = cms.PSet(
00303 lineColor = cms.int32(1),
00304 lineStyle = cms.int32(1),
00305 lineWidth = cms.int32(1),
00306 fillColor = cms.int32(41),
00307 drawOption = cms.string('eBand'),
00308 drawOptionLegend = cms.string('l')
00309 )
00310 )
00311 ),
00312 drawOptionEntries = Utils.SpawnPSet(drawOptModifiers,drawOptStuff)
00313 )
00314
00315 standardCompareTestAndReference = cms.PSet(
00316 processes = cms.PSet(
00317 test = cms.PSet(
00318 dqmDirectory = cms.string('test'),
00319 legendEntry = cms.string('no test label'),
00320 type = cms.string('smMC')
00321 ),
00322 reference = cms.PSet(
00323 dqmDirectory = cms.string('reference'),
00324 legendEntry = cms.string('no ref label'),
00325 type = cms.string('smMC')
00326 )
00327 ),
00328 )
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 """
00380
00381 UTILITIES
00382
00383 """
00384
00385 class ApplyFunctionToSequence:
00386 """ helper class that applies a given function to all modules
00387 in a sequence """
00388 def __init__(self,function):
00389 self.functor = function
00390 def enter(self, module):
00391 self.functor(module)
00392 def leave(self, module):
00393 pass
00394
00395 def TranslateToLegacyProdNames(input):
00396 input = re.sub('fixedConePFTauProducer', 'pfRecoTauProducer', input)
00397
00398 fixedDiscriminationRegex = re.compile('fixedConePFTauDiscrimination(\w*)')
00399 input = fixedDiscriminationRegex.sub(r'pfRecoTauDiscrimination\1', input)
00400 input = re.sub('shrinkingConePFTauProducer', 'pfRecoTauProducerHighEfficiency', input)
00401 shrinkingDiscriminationRegex = re.compile('shrinkingConePFTauDiscrimination(\w*)')
00402 input = shrinkingDiscriminationRegex.sub(r'pfRecoTauDiscrimination\1HighEfficiency', input)
00403 return input
00404
00405
00406 def ConvertDrawJobToLegacyCompare(input):
00407 """ Converts a draw job defined to compare 31X named PFTau validtion efficiencies
00408 to comapre a 31X to a 22X named Validation """
00409
00410 if not hasattr(input, "drawJobs"):
00411 return
00412 myDrawJobs = input.drawJobs.parameters_()
00413 for drawJobName, drawJobData in myDrawJobs.iteritems():
00414 print drawJobData
00415 if not drawJobData.plots.pythonTypeName() == "cms.PSet":
00416 continue
00417 pSetToInsert = cms.PSet(
00418 standardEfficiencyParameters,
00419 plots = cms.VPSet(
00420
00421 cms.PSet(
00422 dqmMonitorElements = drawJobData.plots.dqmMonitorElements,
00423 process = cms.string('test'),
00424 drawOptionEntry = cms.string('eff_overlay01'),
00425 legendEntry = cms.string(input.processes.test.legendEntry.value())
00426 ),
00427
00428 cms.PSet(
00429
00430 dqmMonitorElements = cms.vstring(TranslateToLegacyProdNames(drawJobData.plots.dqmMonitorElements.value()[0])),
00431 process = cms.string('reference'),
00432 drawOptionEntry = cms.string('eff_overlay02'),
00433 legendEntry = cms.string(input.processes.reference.legendEntry.value())
00434 )
00435 )
00436 )
00437 input.drawJobs.__setattr__(drawJobName, pSetToInsert)
00438
00439 def MakeLabeler(TestLabel, ReferenceLabel):
00440 def labeler(module):
00441 if hasattr(module, 'processes'):
00442 if module.processes.hasParameter(['test', 'legendEntry']) and module.processes.hasParameter([ 'reference', 'legendEntry']):
00443 module.processes.test.legendEntry = TestLabel
00444 module.processes.reference.legendEntry = ReferenceLabel
00445 print "Set test label to %s and reference label to %s for plot producer %s" % (TestLabel, ReferenceLabel, module.label())
00446 else:
00447 print "ERROR in RecoTauValidation_cfi::MakeLabeler - trying to set test/reference label but %s does not have processes.(test/reference).legendEntry parameters!" % module.label()
00448 return labeler
00449
00450 def SetYmodulesToLog(matchingNames = []):
00451 ''' set all modules whose name contains one of the matching names to log y scale'''
00452 def yLogger(module):
00453 ''' set a module to use log scaling in the yAxis'''
00454 if hasattr(module, 'drawJobs'):
00455 print "EK DEBUG"
00456 drawJobParamGetter = lambda subName : getattr(module.drawJobs, subName)
00457
00458 attrNames = dir(module.drawJobs)
00459 for subModuleName, subModule in zip(attrNames, map(drawJobParamGetter, attrNames)):
00460 matchedNames = [name for name in matchingNames if subModuleName.find( name) > -1]
00461 if len(matchingNames) == 0:
00462 matchedNames = ['take','everything','and','dont','bother']
00463 if hasattr(subModule, "yAxis") and len(matchedNames):
00464 print "Setting drawJob: ", subModuleName, " to log scale."
00465 subModule.yAxis = cms.string('fakeRate')
00466 if len(matchingNames) == 0:
00467 module.yAxes.efficiency.maxY_log = 40
00468 module.yAxes.fakeRate.maxY_log = 40
00469 return yLogger
00470
00471
00472 def SetBaseDirectory(Directory):
00473 def BaseDirectorizer(module):
00474 newPath = Directory
00475
00476 if hasattr(module, "outputFilePath"):
00477 oldPath = module.outputFilePath.value()
00478 newPath = os.path.join(newPath, oldPath)
00479 if not os.path.exists(newPath):
00480 os.makedirs(newPath)
00481 print newPath
00482 module.outputFilePath = cms.string("%s" % newPath)
00483 return BaseDirectorizer
00484
00485 def RemoveComparisonPlotCommands(module):
00486 if hasattr(module, 'drawJobs'):
00487
00488 drawJobs = module.drawJobs.parameterNames_()
00489 for drawJob in drawJobs:
00490 if drawJob != "TauIdEffStepByStep":
00491 module.drawJobs.__delattr__(drawJob)
00492 print "Removing comparison plot", drawJob
00493
00494 def SetPlotDirectory(myPlottingSequence, directory):
00495 myFunctor = ApplyFunctionToSequence(SetBaseDirectory(directory))
00496 myPlottingSequence.visit(myFunctor)
00497
00498 def SetTestAndReferenceLabels(myPlottingSequence, TestLabel, ReferenceLabel):
00499 myFunctor = ApplyFunctionToSequence(MakeLabeler(TestLabel, ReferenceLabel))
00500 myPlottingSequence.visit(myFunctor)
00501
00502 def SetCompareToLegacyProductNames(myPlottingSequence):
00503 myFunctor = ApplyFunctionToSequence(ConvertDrawJobToLegacyCompare)
00504 myPlottingSequence.visit(myFunctor)
00505
00506 def SetTestFileToPlot(myProcess, FileLoc):
00507 myProcess.loadTau.test.inputFileNames = cms.vstring(FileLoc)
00508
00509 def SetReferenceFileToPlot(myProcess, FileLoc):
00510 if FileLoc == None:
00511 del myProcess.loadTau.reference
00512 else:
00513 myProcess.loadTau.reference.inputFileNames = cms.vstring(FileLoc)
00514
00515 def SetLogScale(myPlottingSequence):
00516 myFunctor = ApplyFunctionToSequence(SetYmodulesToLog())
00517 myPlottingSequence.visit(myFunctor)
00518
00519 def SetSmartLogScale(myPlottingSequence):
00520 myFunctor = ApplyFunctionToSequence(SetYmodulesToLog(['Electron', 'Muon', 'Isolation', 'TaNC']))
00521 myPlottingSequence.visit(myFunctor)
00522
00523 def SetPlotOnlyStepByStep(myPlottingSequence):
00524 myFunctor = ApplyFunctionToSequence(RemoveComparisonPlotCommands)
00525 myPlottingSequence.visit(myFunctor)
00526
00527 def SetValidationExtention(module, extension):
00528 module.ExtensionName = module.ExtensionName.value()+extension
00529
00530 def setBinning(module,pset):
00531 if module._TypedParameterizable__type == 'TauTagValidation':
00532 module.histoSettings = pset
00533
00534 def setTrigger(module,pset):
00535 if hasattr(module,'_TypedParameterizable__type') and module._TypedParameterizable__type == 'TauTagValidation':
00536 setattr(module,'turnOnTrigger',cms.bool(True))
00537 for item in pset.parameters_().items():
00538 setattr(module.GenericTriggerSelection,item[0],item[1])