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.PFTausHighEfficiencyLeadingPionBothProngs = cms.EDAnalyzer("TauTagValidation",
00115 StandardMatchingParameters,
00116 GenericTriggerSelection = GenericTriggerSelectionParameters,
00117 ExtensionName = cms.string("LeadingPion"),
00118 TauProducer = cms.InputTag('shrinkingConePFTauProducer'),
00119 discriminators = cms.VPSet(
00120 cms.PSet( discriminator = cms.string("shrinkingConePFTauDiscriminationByLeadingTrackFinding"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00121 cms.PSet( discriminator = cms.string("shrinkingConePFTauDiscriminationByLeadingPionPtCut"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00122 cms.PSet( discriminator = cms.string("shrinkingConePFTauDiscriminationByTrackIsolationUsingLeadingPion"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00123 cms.PSet( discriminator = cms.string("shrinkingConePFTauDiscriminationByECALIsolationUsingLeadingPion"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00124 cms.PSet( discriminator = cms.string("shrinkingConePFTauDiscriminationAgainstElectron"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00125 cms.PSet( discriminator = cms.string("shrinkingConePFTauDiscriminationAgainstMuon"),selectionCut = cms.double(0.5),plotStep = cms.bool(True))
00126 )
00127 )
00128
00129 proc.RunHPSValidation = proc.PFTausHighEfficiencyLeadingPionBothProngs.clone()
00130 proc.RunHPSValidation.ExtensionName = ""
00131
00132 proc.RunHPSValidation.TauProducer = cms.InputTag('hpsPFTauProducer')
00133 proc.RunHPSValidation.discriminators = cms.VPSet(
00134 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByDecayModeFinding"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00135 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByVLooseChargedIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00136 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseChargedIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00137 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightChargedIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00138 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseIsolation"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00139 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByVLooseCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00140 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00141 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMediumCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00142 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightCombinedIsolationDBSumPtCorr"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00143 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00144 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMediumElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00145 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00146 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByLooseMuonRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00147 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMediumMuonRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(True)),
00148 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByTightMuonRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00149 cms.PSet( discriminator = cms.string("hpsPFTauDiscriminationByMVAElectronRejection"),selectionCut = cms.double(0.5),plotStep = cms.bool(False)),
00150 )
00151
00152 proc.TauValNumeratorAndDenominator = cms.Sequence(
00153 proc.PFTausHighEfficiencyLeadingPionBothProngs+
00154 proc.RunHPSValidation
00155 )
00156
00157 """
00158
00159 EFFICIENCY
00160
00161 Tau efficiency calculations
00162
00163 Define the Efficiency curves to produce. Each
00164 efficiency producer takes the numberator and denominator
00165 histograms and the dependent variables.
00166 """
00167
00168 plotPset = Utils.SetPlotSequence(proc.TauValNumeratorAndDenominator)
00169 proc.efficiencies = cms.EDAnalyzer(
00170 "TauDQMHistEffProducer",
00171 plots = plotPset
00172 )
00173
00174
00175
00176
00177
00178
00179
00180
00181 proc.normalizePlots = cms.EDAnalyzer(
00182 "DQMHistNormalizer",
00183 plotNamesToNormalize = cms.vstring('*_pTRatio_*','*_Size_*','*_SumPt_*','*_dRTauRefJet*'),
00184 reference = cms.string('*_pTRatio_allHadronic')
00185 )
00186
00187 proc.TauEfficiencies = cms.Sequence(
00188 proc.efficiencies*
00189 proc.normalizePlots
00190 )
00191
00192 """
00193
00194 PLOTTING
00195
00196 loadTau: load two separate TauVal root files into the DQM
00197 so the plotter can access them
00198
00199 """
00200
00201 loadTau = cms.EDAnalyzer("TauDQMFileLoader",
00202 test = cms.PSet(
00203
00204 inputFileNames = cms.vstring('/opt/sbg/cms/ui4_data1/dbodin/CMSSW_3_5_1/src/TauID/QCD_recoFiles/TauVal_CMSSW_3_6_0_QCD.root'),
00205 scaleFactor = cms.double(1.),
00206 dqmDirectory_store = cms.string('test')
00207 ),
00208 reference = cms.PSet(
00209 inputFileNames = cms.vstring('/opt/sbg/cms/ui4_data1/dbodin/CMSSW_3_5_1/src/TauID/QCD_recoFiles/TauVal_CMSSW_3_6_0_QCD.root'),
00210 scaleFactor = cms.double(1.),
00211 dqmDirectory_store = cms.string('reference')
00212 )
00213 )
00214
00215
00216
00217
00218 xAxisStuff = cms.PSet(
00219 xAxisTitle = cms.string('P_{T} / GeV'),
00220 xAxisTitleOffset = cms.double(0.9),
00221 xAxisTitleSize = cms.double(0.05)
00222 )
00223 xModifiers = [['pt',['xAxisTitle'],['P_{T} / GeV']],['eta',['xAxisTitle'],['#eta']],['phi',['xAxisTitle'],['#phi']],['pileup',['xAxisTitle'],['# of Reco Vertices']]]
00224
00225 yAxisStuff =cms.PSet(
00226 yScale = cms.string('linear'),
00227 minY_linear = cms.double(0.),
00228 maxY_linear = cms.double(1.6),
00229 minY_log = cms.double(0.001),
00230 maxY_log = cms.double(1.8),
00231 yAxisTitle = cms.string('#varepsilon'),
00232 yAxisTitleOffset = cms.double(1.1),
00233 yAxisTitleSize = cms.double(0.05)
00234 )
00235 yModifiers = [['efficiency',['yScale','yAxisTitle'],['linear','#varepsilon']],['fakeRate',['yScale','yAxisTitle'],['log','Fake rate']]]
00236
00237 legStuff = cms.PSet(
00238 posX = cms.double(0.50),
00239 posY = cms.double(0.72),
00240 sizeX = cms.double(0.39),
00241 sizeY = cms.double(0.17),
00242 header = cms.string(''),
00243 option = cms.string('brNDC'),
00244 borderSize = cms.int32(0),
00245 fillColor = cms.int32(0)
00246 )
00247 legModifiers = [['efficiency',['posY','sizeY'],[0.72,0.17]],['efficiency_overlay',['posY','sizeY'],[0.66,0.23]]]
00248
00249 drawOptStuff = cms.PSet(
00250 markerColor = cms.int32(1),
00251 markerSize = cms.double(1.),
00252 markerStyle = cms.int32(20),
00253 lineColor = cms.int32(1),
00254 lineStyle = cms.int32(1),
00255 lineWidth = cms.int32(2),
00256 drawOption = cms.string('ex0'),
00257 drawOptionLegend = cms.string('p')
00258 )
00259 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]]]
00260
00261 standardDrawingStuff = cms.PSet(
00262 canvasSizeX = cms.int32(640),
00263 canvasSizeY = cms.int32(640),
00264 indOutputFileName = cms.string('#PLOT#.png'),
00265 xAxes = Utils.SpawnPSet(xModifiers,xAxisStuff),
00266 yAxes = Utils.SpawnPSet(yModifiers,yAxisStuff),
00267 legends = Utils.SpawnPSet(legModifiers,legStuff),
00268 labels = cms.PSet(
00269 pt = cms.PSet(
00270 posX = cms.double(0.19),
00271 posY = cms.double(0.77),
00272 sizeX = cms.double(0.12),
00273 sizeY = cms.double(0.04),
00274 option = cms.string('brNDC'),
00275 borderSize = cms.int32(0),
00276 fillColor = cms.int32(0),
00277 textColor = cms.int32(1),
00278 textSize = cms.double(0.04),
00279 textAlign = cms.int32(22),
00280 text = cms.vstring('P_{T} > 5 GeV')
00281 ),
00282 eta = cms.PSet(
00283 posX = cms.double(0.19),
00284 posY = cms.double(0.83),
00285 sizeX = cms.double(0.12),
00286 sizeY = cms.double(0.04),
00287 option = cms.string('brNDC'),
00288 borderSize = cms.int32(0),
00289 fillColor = cms.int32(0),
00290 textColor = cms.int32(1),
00291 textSize = cms.double(0.04),
00292 textAlign = cms.int32(22),
00293 text = cms.vstring('-2.5 < #eta < +2.5')
00294 )
00295 ),
00296 drawOptionSets = cms.PSet(
00297 efficiency = cms.PSet(
00298 test = cms.PSet(
00299 markerColor = cms.int32(4),
00300 markerSize = cms.double(1.),
00301 markerStyle = cms.int32(20),
00302 lineColor = cms.int32(1),
00303 lineStyle = cms.int32(1),
00304 lineWidth = cms.int32(1),
00305 drawOption = cms.string('ep'),
00306 drawOptionLegend = cms.string('p')
00307 ),
00308 reference = cms.PSet(
00309 lineColor = cms.int32(1),
00310 lineStyle = cms.int32(1),
00311 lineWidth = cms.int32(1),
00312 fillColor = cms.int32(41),
00313 drawOption = cms.string('eBand'),
00314 drawOptionLegend = cms.string('l')
00315 )
00316 )
00317 ),
00318 drawOptionEntries = Utils.SpawnPSet(drawOptModifiers,drawOptStuff)
00319 )
00320
00321 standardCompareTestAndReference = cms.PSet(
00322 processes = cms.PSet(
00323 test = cms.PSet(
00324 dqmDirectory = cms.string('test'),
00325 legendEntry = cms.string('no test label'),
00326 type = cms.string('smMC')
00327 ),
00328 reference = cms.PSet(
00329 dqmDirectory = cms.string('reference'),
00330 legendEntry = cms.string('no ref label'),
00331 type = cms.string('smMC')
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
00382
00383
00384
00385 """
00386
00387 UTILITIES
00388
00389 """
00390
00391 class ApplyFunctionToSequence:
00392 """ helper class that applies a given function to all modules
00393 in a sequence """
00394 def __init__(self,function):
00395 self.functor = function
00396 def enter(self, module):
00397 self.functor(module)
00398 def leave(self, module):
00399 pass
00400
00401 def TranslateToLegacyProdNames(input):
00402 input = re.sub('fixedConePFTauProducer', 'pfRecoTauProducer', input)
00403
00404 fixedDiscriminationRegex = re.compile('fixedConePFTauDiscrimination(\w*)')
00405 input = fixedDiscriminationRegex.sub(r'pfRecoTauDiscrimination\1', input)
00406 input = re.sub('shrinkingConePFTauProducer', 'pfRecoTauProducerHighEfficiency', input)
00407 shrinkingDiscriminationRegex = re.compile('shrinkingConePFTauDiscrimination(\w*)')
00408 input = shrinkingDiscriminationRegex.sub(r'pfRecoTauDiscrimination\1HighEfficiency', input)
00409 return input
00410
00411
00412 def ConvertDrawJobToLegacyCompare(input):
00413 """ Converts a draw job defined to compare 31X named PFTau validtion efficiencies
00414 to comapre a 31X to a 22X named Validation """
00415
00416 if not hasattr(input, "drawJobs"):
00417 return
00418 myDrawJobs = input.drawJobs.parameters_()
00419 for drawJobName, drawJobData in myDrawJobs.iteritems():
00420 print drawJobData
00421 if not drawJobData.plots.pythonTypeName() == "cms.PSet":
00422 continue
00423 pSetToInsert = cms.PSet(
00424 standardEfficiencyParameters,
00425 plots = cms.VPSet(
00426
00427 cms.PSet(
00428 dqmMonitorElements = drawJobData.plots.dqmMonitorElements,
00429 process = cms.string('test'),
00430 drawOptionEntry = cms.string('eff_overlay01'),
00431 legendEntry = cms.string(input.processes.test.legendEntry.value())
00432 ),
00433
00434 cms.PSet(
00435
00436 dqmMonitorElements = cms.vstring(TranslateToLegacyProdNames(drawJobData.plots.dqmMonitorElements.value()[0])),
00437 process = cms.string('reference'),
00438 drawOptionEntry = cms.string('eff_overlay02'),
00439 legendEntry = cms.string(input.processes.reference.legendEntry.value())
00440 )
00441 )
00442 )
00443 input.drawJobs.__setattr__(drawJobName, pSetToInsert)
00444
00445 def MakeLabeler(TestLabel, ReferenceLabel):
00446 def labeler(module):
00447 if hasattr(module, 'processes'):
00448 if module.processes.hasParameter(['test', 'legendEntry']) and module.processes.hasParameter([ 'reference', 'legendEntry']):
00449 module.processes.test.legendEntry = TestLabel
00450 module.processes.reference.legendEntry = ReferenceLabel
00451 print "Set test label to %s and reference label to %s for plot producer %s" % (TestLabel, ReferenceLabel, module.label())
00452 else:
00453 print "ERROR in RecoTauValidation_cfi::MakeLabeler - trying to set test/reference label but %s does not have processes.(test/reference).legendEntry parameters!" % module.label()
00454 return labeler
00455
00456 def SetYmodulesToLog(matchingNames = []):
00457 ''' set all modules whose name contains one of the matching names to log y scale'''
00458 def yLogger(module):
00459 ''' set a module to use log scaling in the yAxis'''
00460 if hasattr(module, 'drawJobs'):
00461 print "EK DEBUG"
00462 drawJobParamGetter = lambda subName : getattr(module.drawJobs, subName)
00463
00464 attrNames = dir(module.drawJobs)
00465 for subModuleName, subModule in zip(attrNames, map(drawJobParamGetter, attrNames)):
00466 matchedNames = [name for name in matchingNames if subModuleName.find( name) > -1]
00467 if len(matchingNames) == 0:
00468 matchedNames = ['take','everything','and','dont','bother']
00469 if hasattr(subModule, "yAxis") and len(matchedNames):
00470 print "Setting drawJob: ", subModuleName, " to log scale."
00471 subModule.yAxis = cms.string('fakeRate')
00472 if len(matchingNames) == 0:
00473 module.yAxes.efficiency.maxY_log = 40
00474 module.yAxes.fakeRate.maxY_log = 40
00475 return yLogger
00476
00477
00478 def SetBaseDirectory(Directory):
00479 def BaseDirectorizer(module):
00480 newPath = Directory
00481
00482 if hasattr(module, "outputFilePath"):
00483 oldPath = module.outputFilePath.value()
00484 newPath = os.path.join(newPath, oldPath)
00485 if not os.path.exists(newPath):
00486 os.makedirs(newPath)
00487 print newPath
00488 module.outputFilePath = cms.string("%s" % newPath)
00489 return BaseDirectorizer
00490
00491 def RemoveComparisonPlotCommands(module):
00492 if hasattr(module, 'drawJobs'):
00493
00494 drawJobs = module.drawJobs.parameterNames_()
00495 for drawJob in drawJobs:
00496 if drawJob != "TauIdEffStepByStep":
00497 module.drawJobs.__delattr__(drawJob)
00498 print "Removing comparison plot", drawJob
00499
00500 def SetPlotDirectory(myPlottingSequence, directory):
00501 myFunctor = ApplyFunctionToSequence(SetBaseDirectory(directory))
00502 myPlottingSequence.visit(myFunctor)
00503
00504 def SetTestAndReferenceLabels(myPlottingSequence, TestLabel, ReferenceLabel):
00505 myFunctor = ApplyFunctionToSequence(MakeLabeler(TestLabel, ReferenceLabel))
00506 myPlottingSequence.visit(myFunctor)
00507
00508 def SetCompareToLegacyProductNames(myPlottingSequence):
00509 myFunctor = ApplyFunctionToSequence(ConvertDrawJobToLegacyCompare)
00510 myPlottingSequence.visit(myFunctor)
00511
00512 def SetTestFileToPlot(myProcess, FileLoc):
00513 myProcess.loadTau.test.inputFileNames = cms.vstring(FileLoc)
00514
00515 def SetReferenceFileToPlot(myProcess, FileLoc):
00516 if FileLoc == None:
00517 del myProcess.loadTau.reference
00518 else:
00519 myProcess.loadTau.reference.inputFileNames = cms.vstring(FileLoc)
00520
00521 def SetLogScale(myPlottingSequence):
00522 myFunctor = ApplyFunctionToSequence(SetYmodulesToLog())
00523 myPlottingSequence.visit(myFunctor)
00524
00525 def SetSmartLogScale(myPlottingSequence):
00526 myFunctor = ApplyFunctionToSequence(SetYmodulesToLog(['Electron', 'Muon', 'Isolation', 'TaNC']))
00527 myPlottingSequence.visit(myFunctor)
00528
00529 def SetPlotOnlyStepByStep(myPlottingSequence):
00530 myFunctor = ApplyFunctionToSequence(RemoveComparisonPlotCommands)
00531 myPlottingSequence.visit(myFunctor)
00532
00533 def SetValidationExtention(module, extension):
00534 module.ExtensionName = module.ExtensionName.value()+extension
00535
00536 def setBinning(module,pset):
00537 if module._TypedParameterizable__type == 'TauTagValidation':
00538 module.histoSettings = pset
00539
00540 def setTrigger(module,pset):
00541 if hasattr(module,'_TypedParameterizable__type') and module._TypedParameterizable__type == 'TauTagValidation':
00542 setattr(module,'turnOnTrigger',cms.bool(True))
00543 for item in pset.parameters_().items():
00544 setattr(module.GenericTriggerSelection,item[0],item[1])