PAT Examples: Top Quark Analysis



After having discussed many details and aspects of PAT during Exercise01 to Exercise10 of the regular PAT Tutorial we would like to flash a more comprehensive example for the use of PAT including the interplay of many of these aspects in a real life experiment. We have chosen the TopPAG Lepton+Jets reference selection that was used for the synchronisation of different analyses in the preparation for the latest results for the ICHEP2010. You can find these results summarised here.

We will concentrate on the selection of events containing top quark pairs in the semi-leptonic decay channel with a muon in the final state. These events are characterised by:

  • an isolated high pt muon with large transverse momentum.
  • four jets with large transverse momentum.
  • two jets originating from b-quarks.
  • missing transverse momentum (MET).

You can find a sketch of such an event below:


The reference selection mostly makes use of the isolated high pt muon. It consists of a loose and a tight selection path, which are divided in up to seven steps. We give a slightly reduced table as it was used for the synchronisation exercises below:

Step Selection Comments/details/code snippets
1 HLT_Mu9 pass single muon trigger (trigger menu 8E29)
  NO other bits needed (bit 0, tech triggers, beam halo ...)
2 Primary vertex existence of a good primary vertex, satisfying
not(isFake) && ndof>4 && abs(z)<15 && ρ<2.0
3a Muon selection exactly one muon with the following requirements:
o GlobalMuon && TrackerMuon
o pT>20 GeV
o fabs(eta)<2.1
o relIso=(mu.trackIso()+mu.ecalIso()+mu.hcalIso())/muon.pT<0.05 (isolation cones dR=0.3)
o isGlobalMuonPromptTight, i.e.:
- muon.globalTrack()->normalizedChi2()<10.0
- muon.globalTrack()->hitPattern().numberOfValidMuonHits()>0
o Number of Hits in the silicon tracker NHits>10
o ΔR(μ,jet)>0.3 where jet is any jet passing the jet requirements listed in step 6
o absolute 2D impact parameter d0(Bsp)<0.02cm using muon.dB() of the pat::Muon (i.e. w.r.t. the average beam spot using the innerTrack (tracker track) of the muon)
NOTE! You must set process.patMuons.usePV = False to set the dB to the beamspot.
3b Alternatively to 3a same as 3a, but relIso<0.1
4 Loose muon veto Reject event containing an additional (looser) muon, defined as:
o GlobalMuon
o pT>10 GeV, fabs(eta)<2.5
o relIso=(mu.trackIso()+mu.ecalIso()+mu.hcalIso())/muon.pT<0.2 (isolation cones dR=0.3)
5 Electron veto Reject event containing an electron, defined as:
o ET>15 GeV, fabs(eta)<2.5
o relIso=(ele.dr03TkSumPt()+ele.dr03EcalRecHitSumEt()+ele.dr03HcalTowerSumEt())/<0.2 (isolation cones dR=0.3)
6a,b,c >= 1,2,3 jets using antikt5CaloJets (L2L3 corrected) fulfilling:
o pT>30 GeV
o fabs(eta)<2.4
o jet ID, emf (electromagnetic fraction)>0.01 (patJets->emf())
o jet ID, n90Hits>1 (minimal number of RecHits containing 90% of the jet energy) (patJets->jetID().n90Hits)
o jet ID, fHPD<0.98 (fraction of energy in the hottest HPD readout) (patJets->jetID().fHPD)
7 >= 4 jets same as step 6, but requesting at least 4 jets

Data and selection strategy

For this example we use ~2 pb-1 of the PromptReco Muon skim ( /Mu/Run2010A-PromptReco-v4/RECO ) as indicated on DBS. The considered simulated samples and event numbers are given below:

Sample Cross Section Considered Events Corresp. Lumi link to DBS
ttbar (madgraph) 165 pb 1,000 6.06 pb-1 here
zjets (madgraph) 3,110 pb 10,000 3.21 pb-1 here
wjets (madgraph) 28,000 pb 100,000 3.57 pb-1 here
QCD (pythia) (1) 86,101 pb 3000,000 3.48 pb-1 here

(1) Corresponding to a muon enriched QCD sample.

We reduced the number of simulated events that we take into account to keep the amount of processing time manageable. The selection strategy starts from a customised PAT tuple, based on selectedPatCandidates. In a real life measurement you would most probably produce these PAT tuples using crab as detailed in Exercise 3.

Based on these PAT tuples we apply each of the seven selection steps following two selection paths corresponding to the tight (3a) and loose (3b) selection scenario with tighter or more relaxed requirements on the muon isolation. For the monitoring we extended the PatBasicAnalyzer from Exercise 4 to get a rough picture of the involved objects. To monitor them we interleave each selection step with a monitoring unit. Our choice fell on a full CMSSW implementation as we can easily make use of the SWGuidePhysicsCutParser for an intuitive and flexible object selection and re-apply the monitoring module before and/or after each selection step. The idea is to compare the event yield from data with the expectation from the simulation.

ALERT! Note: For fairness we should mention that for an analysis of this scale it is more suited to run on a batch system and to divide the work into smaller subjobs. To do the exercise indicated below on a shorter time scale you might want to divide all event yields by a factor of 10 or more.

Setting up of the environment

First of all connect to lxplus and go to some working directory. You can choose any directory, provided that you have enough space. You need ~5 MB of free disc space for this exercise. We recommend you to use your ~/scratch0 space. In case you don't have this (or do not even know what it is) check your quota typing fs lq and follow this link. If you don't have enough space, you may instead use the temporary space (/tmp/your_user_name), but be aware that this is lost once you log out of lxplus (or within something like a day). We will expect in the following that you have such a ~/scratch0 directory.

ssh lxplus
[ ... enter password ... ]
cd scratch0/

Create a directory for this exercise (to avoid interference with code from the other exercises).

mkdir topPAG
cd topPAG

Create a local release area and enter it.

cmsrel CMSSW_5_3_14
cd CMSSW_5_3_14/src 

The first command creates all directories needed in a local release area. Setting up the environment is done invoking the following script:


PAT tuple production

We start the exercise with the configuration file for the customised PAT tuple production. Checkout and compile the PatExamples package.

addpkg PhysicsTools/PatExamples V00-05-23
scram b PhysicsTools/PatExamples
(Instead of "addpkg PhysicsTools/PatExamples V00-05-23", "git cms-addpkg PhysicsTools/PatExamples" worked (Aug 16, 2014).)

ALERT! Note: You might want to use more than one core to compile the package making use of the scram compiler flag -j followed by the number of cores you would like to make use of.

To safe some time we have already produced the customised PAT tuples for you, starting from the file as described in Exercise 2. You can find these PAT tuples for the data and the various samples under:

rfdir /castor/
-rw-r--r--   1 cmssup   zh                  172500977 Sep 16 19:12 patTuple_wjets_0.root
-rw-r--r--   1 cmssup   zh                  172832053 Sep 16 19:12 patTuple_wjets_1.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_2.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_3.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_4.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_42X.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_5.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_6.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_7.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_8.root
-rw-r--r--   1 cmssup   zh                  173885178 Sep 16 19:13 patTuple_wjets_9.root

ALERT! Note: You will find these files only on castor at cern. When you are trying to do this exercise from some workgroup server pool outside cern you should check that these pat tuples are available and accessible there.

Have a look into the file to learn more about the customisations that we applied:

## import skeleton process
from PhysicsTools.PatAlgos.patTemplate_cfg import *

## ---
## adjust inputs if necessary
## ---
##from import run36xOn35xInput

## --- 
## adjust workflow to need in TopPAG
## ---
from import *
removeMCMatching(process, ['All'])
removeSpecificPATObjects(process, ['Photons','Taus'])

## ---
## adjust content
## ---
process.patMuons.usePV      = False
process.patMuons.embedTrack = True

## define event content
from PhysicsTools.PatAlgos.patEventContent_cff import patEventContentNoCleaning
process.out.outputCommands = cms.untracked.vstring('drop *', *patEventContentNoCleaning ) 
process.out.outputCommands+= [ 'keep edmTriggerResults_*_*_*',
                               'keep *_offlinePrimaryVertices_*_*'

process.p = cms.Path(

ALERT! Note: Due to technical reasons we had to adjust the workflow for the simulated events that had been produced within the CMSSW_3_5_X release series. You don't have to do this when testing the configuration file with the standard ttbar input sample that we used for the PAT Tutorial. Therefore we commented these lines here. ( In general it turns out that often when starting an analysis you have to check the exact event content of the samples that you are planning to use sample by sample and adjust the configuration accordingly. ) We dropped the photons and tau leptons from the content as we will not make further use of them and switched the MC matching and object cross cleaning off. We made sure to make use of the most actual JEC constants, added L5Flavor corrections as derived from simulated ttbar events, defined the impact parameter for muons with respect to the beamspot (in contrary to the primary vertex) and embedded the reco::Track information into the pat:.Muon as we later on want to apply selection requirements on it. We saved all edmTriggerResults (for selection step 1), the offlinePrimaryVertices collection (for selection step 2) and all remaining selectedPatCandidates into the PAT tuple. Many of the functions and steps applied in this file you encountered during Exercise 5 and Exercise 6.

You should run this configuration file once on a few events of the standard ttbar input sample that we used for the PAT Tutorial to convince yourself that it works and that you understand what it is doing.

ALERT! Note: The patTuple_topPreproduction_cfg.py_configuration file makes use of the a default file used for data validation at cern! When taken literally this example only works when working on _lxplus. If you want to try this example from somewhere else you have to adapt the input file.

[rwolf@lxplus231]~/scratch0/CMSSW_5_3_14/src% cmsRun PhysicsTools/PatExamples/test/
removed from lepton counter: taus
INFO   : some objects have been removed from the sequence. Switching 
         off PAT cross collection cleaning, as it might be of limited
         sense now. If you still want to keep object collection cross
         cleaning within PAT you need to run and configure it by hand
INFO   : cleaning has been removed. Switch output from clean PAT     
         candidates to selected PAT candidates.
************** MC dependence removal ************
removing MC dependencies for photons
removing MC dependencies for electrons
removing MC dependencies for muons
removing MC dependencies for taus
WARNING: called applyPostfix for module/sequence tauGenJets which is not in patDefaultSequence!
WARNING: called applyPostfix for module/sequence tauGenJetsSelectorAllHadrons which is not in patDefaultSequence!
WARNING: called applyPostfix for module/sequence tauGenJetMatch which is not in patDefaultSequence!
removing MC dependencies for jets
WARNING: called applyPostfix for module/sequence cleanPatCandidates which is not in patDefaultSequence!
INFO   : cleaning has been removed. Switch output from clean PAT     
         candidates to selected PAT candidates.
20-Sep-2010 19:02:04 CEST  Initiating request to open file rfio:/castor/
20-Sep-2010 19:02:16 CEST  Successfully opened file rfio:/castor/
Begin processing the 1st record. Run 1, Event 1001, LumiSection 777787 at 20-Sep-2010 19:02:25 CEST
Begin processing the 2nd record. Run 1, Event 1002, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 3rd record. Run 1, Event 1003, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 4th record. Run 1, Event 1004, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 5th record. Run 1, Event 1005, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 6th record. Run 1, Event 1006, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 7th record. Run 1, Event 1007, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 8th record. Run 1, Event 1008, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST
Begin processing the 9th record. Run 1, Event 1009, LumiSection 777787 at 20-Sep-2010 19:02:37 CEST

You can check the event content of the resulting PAT tuple making use of the edmDumpEventContent tool:

[rwolf@lxplus231]~/scratch0/CMSSW_%PATRELEASE%/src% edmDumpEventContent patTuple.root 

  *                                         *
  * Welcome to my .rootlogon.C!!!           *
  *                                         *
  * ...Define MyStyle 22.01.07...           *
  * ...Load CMSSW libraries...              *
  *                                         *
  * ...done                                 *
  *                                         *

edm::TriggerResults               "TriggerResults"        ""            "HLT."         
edm::TriggerResults               "TriggerResults"        ""            "RECO."        
vector<reco::Vertex>              "offlinePrimaryVertices"    ""            "RECO."        
edm::OwnVector<reco::BaseTagInfo,edm::ClonePolicy<reco::BaseTagInfo> >     "selectedPatJets"       "tagInfos"    "PAT."         
edm::TriggerResults               "TriggerResults"        ""            "PAT."         
vector<CaloTower>                 "selectedPatJets"       "caloTowers"    "PAT."         
vector<pat::Electron>             "selectedPatElectrons"    ""            "PAT."         
vector<pat::Jet>                  "selectedPatJets"       ""            "PAT."         
vector<pat::MET>                  "patMETs"               ""            "PAT."         
vector<pat::Muon>                 "selectedPatMuons"      ""            "PAT."         
vector<reco::GenJet>              "selectedPatJets"       "genJets"     "PAT."         

Event selection

For the event selection we make use of the file in the test directory of the PatExamples package. It contains the pre-processed PAT tuples for the simulated ttbar events as input, you can just execute it as it is:

cmsRun PhysicsTools/PatExamples/test/

We are going to have a closer look into the structure of the file while the first job is running. Apart from the obligatory input source and TFileService declaration it consists of four sections. We will go through them step by step in the following:

## ----------------------------------------------------------------
## Apply object selection according to TopPAG reference selection
## for ICHEP 2010. This will result in 5 additional collections:
## * goodJets
## * vetoElecs
## * vetoMuons
## * looseMuons
## * tightMuons
## Have a look ont the cff file to learn more about the exact
## selection citeria.
## ----------------------------------------------------------------
process.topObjectProduction = cms.Path(

ALERT! Note: In this section all objects that will be needed for the event selection are created beforehand. These are object collections for which we applied the object requirements as defined in the selection table above. We have chosen the module labels pretty self-explaining if you have the above table in mind:

  • tightMuons
  • looseMuons
  • vetoMuons
  • vetoElecs
  • goodJets

All of them are pat::Candidate collections that have the corresponding default selectedPatCandidate collections as input. You can find their definitions in the indicated cff file. We will only discuss the muon collections here, the others are derived in an analogue way:

## ---
## this cff file keep all object selections used for the TopPAG
## reference selection for ICHEP 2010
## ---
from PhysicsTools.PatAlgos.cleaningLayer1.muonCleaner_cfi import *
looseMuons = cleanPatMuons.clone(
    preselection =
    'isGlobalMuon & isTrackerMuon &'
    'pt > 20. &'
    'abs(eta) < 2.1 &'
    '(trackIso+caloIso)/pt < 0.1 &'
    'innerTrack.numberOfValidHits > 10 &'
    'globalTrack.normalizedChi2 < 10.0 &'
    'globalTrack.hitPattern.numberOfValidMuonHits > 0 &'
    'abs(dB) < 0.02',
    checkOverlaps = cms.PSet(
      jets = cms.PSet(
        src                 = cms.InputTag("goodJets"),
        algorithm           = cms.string("byDeltaR"),
        preselection        = cms.string(""),
        deltaR              = cms.double(0.3),
        checkRecoComponents = cms.bool(False),
        pairCut             = cms.string(""),
        requireNoOverlaps   = cms.bool(True),

tightMuons = cleanPatMuons.clone(
    src = 'looseMuons',
    preselection = '(trackIso+caloIso)/pt < 0.05'

from PhysicsTools.PatAlgos.selectionLayer1.muonSelector_cfi import *
vetoMuons = selectedPatMuons.clone(
    src = 'selectedPatMuons',
    cut =
    'isGlobalMuon &'
    'pt > 10. &'
    'abs(eta) < 2.5 &'
    '(trackIso+caloIso)/pt < 0.2'

ALERT! Note: We start off from the looseMuons collection for which we clone the cleanPatMuons as defined in the python/cleaningLayer1 directory of the PatAlgos package. We do this to implement the ΔR(μ,jet)>0.3 requirement between the muon and the closest selected jet in <η, φ> space. As this is a requirement on a relation between two objects we cannot simply apply it via the SWGuidePhysicsCutParser. The cut is applied in the parameter set checkOverlaps, where the jet collection we want to check the muons against (goodJets), the overlap checking algorithm (byDeltaR) and the value of deltaR are defined. The switch requireNoOverlaps takes care that muons, which have an overlap are indeed discarded from the collection. For the rest of the selection we make use of the preselection parameter of the cleanPatMuons module. Thus the PAT cleaning that you encountered in Exercise 7 appears in a new light here!

For convenience the tightMuons, which only adds stronger requirements on top of the looseMuons have the latter as input. We do not have to apply the full selection strings again. Note that all parameters, which are not replaced remain the same as defined in the looseMuons module. Note that for the vetoMuons collection there is no ΔR(μ,jet) requirement. It is therefore enough to stay with the selectedPatMuon module. Also for the jet collection and the electron veto collection there is no need to make use of the cleaning module, as there all requirements are applied just on the objects themselves. Accordingly you will see that we cloned the corresponding selectedPatCandidate modules as defined in the python/selectionLayer1 directory of the PatAlgos package to configure the modules for these collections.

We now come to the second block in the

## ----------------------------------------------------------------
## Define the steps for the TopPAG reference selection for ICHEP
## 2010. Have a look at the WorkBookPATExampleTopQuarks. These
## are event selections. They make use of the object selections
## applied in the step above.
## ----------------------------------------------------------------

## Trigger bit (HLT_mu9)
from HLTrigger.HLTfilters.hltHighLevel_cfi import *
process.step1  = hltHighLevel.clone(TriggerResultsTag = "TriggerResults::HLT", HLTPaths = ["HLT_Mu9"])
## Vertex requirement
process.step2  = cms.EDFilter("VertexSelector", src = cms.InputTag("offlinePrimaryVertices"), cut = cms.string("!isFake && ndof > 4 && abs(z) < 15 && position.Rho < 2"), filter = cms.bool(True))
## Exact one tight muon
from PhysicsTools.PatAlgos.selectionLayer1.muonCountFilter_cfi import *
process.step3a = countPatMuons.clone(src = 'tightMuons', minNumber = 1, maxNumber = 1)
## Exact one loose muon
process.step3b = countPatMuons.clone(src = 'looseMuons', minNumber = 1, maxNumber = 1)
## Veto on additional muons 
process.step4  = countPatMuons.clone(src = 'vetoMuons' , maxNumber = 1)
## Veto on additional electrons
from PhysicsTools.PatAlgos.selectionLayer1.electronCountFilter_cfi import *
process.step5  = countPatMuons.clone(src = 'vetoElecs' , maxNumber = 0)
## Different jet multiplicity selections
from PhysicsTools.PatAlgos.selectionLayer1.jetCountFilter_cfi import *
process.step6a = countPatJets.clone(src = 'goodJets'   , minNumber = 1)
process.step6b = countPatJets.clone(src = 'goodJets'   , minNumber = 2)
process.step6c = countPatJets.clone(src = 'goodJets'   , minNumber = 3)
process.step7  = countPatJets.clone(src = 'goodJets'   , minNumber = 4)

ALERT! Note: Here we define the event selection steps, making use of the candidateCountFilters as defined in the python/selectionLayer1 directory of the PatAlgos package. You can very easily connect the module names with the selection steps defined in the selection table. Note that these modules are event filters! While the modules for object selection were producers that created new collections containing the objects that passed the imposed requirements (which could also result into an empty collection) these modules will really discard events in cases where the collections do not fulfill the requirements.

In the third section we configure a set of modules to fill a set of very basic monitoring histograms, with according replacements for the input collections. The purpose of each module instance is pretty clear from its module label.

## ----------------------------------------------------------------
## Define monitoring modules for the event selection. You should
## few this only as an example for an analyses technique including
## full CMSSW features, not as a complete analysis.
## ----------------------------------------------------------------

from PhysicsTools.PatExamples.PatTopSelectionAnalyzer_cfi import *
process.monStart  = analyzePatTopSelection.clone(jets='goodJets')
process.monStep1  = analyzePatTopSelection.clone(jets='goodJets')
process.monStep2  = analyzePatTopSelection.clone(jets='goodJets')
process.monStep3a = analyzePatTopSelection.clone(muons='tightMuons', jets='goodJets')
process.monStep4  = analyzePatTopSelection.clone(muons='vetoMuons' , jets='goodJets')
process.monStep5  = analyzePatTopSelection.clone(muons='vetoMuons', elecs='vetoElecs', jets='goodJets')
process.monStep6a = analyzePatTopSelection.clone(muons='vetoMuons', elecs='vetoElecs', jets='goodJets')
process.monStep6b = analyzePatTopSelection.clone(muons='vetoMuons', elecs='vetoElecs', jets='goodJets')
process.monStep6c = analyzePatTopSelection.clone(muons='vetoMuons', elecs='vetoElecs', jets='goodJets')
process.monStep7  = analyzePatTopSelection.clone(muons='vetoMuons', elecs='vetoElecs', jets='goodJets')

ALERT! Note: You can find the module definition in the file in the python directory of the PatExamples package. We shortly flash it below:

analyzePatTopSelection = cms.EDAnalyzer("PatTopSelectionAnalyzer",
    elecs = cms.untracked.InputTag("selectedPatElectrons"),
    muons = cms.untracked.InputTag("selectedPatMuons"),                                             
    jets  = cms.untracked.InputTag("selectedPatJets"),
    met   = cms.untracked.InputTag("patMETs")

Indeed it's a modification of the PatBasicAnalyzer that you encountered in Exercise 4. The histograms that we are going to monitor are defined in the implementation of the module. We show the important excerpt below:

// book histograms:
  hists_["yield"   ]=fs->make<TH1F>("yield"   , "electron multiplicity",   1, 0.,   1.);
  hists_["elecMult"]=fs->make<TH1F>("elecMult", "electron multiplicity",  10, 0.,  10.);
  hists_["elecIso" ]=fs->make<TH1F>("elecIso" , "electron isolation"   ,  20, 0.,   1.);
  hists_["elecPt"  ]=fs->make<TH1F>("elecPt"  , "electron pt"          ,  30, 0., 150.);
  hists_["muonMult"]=fs->make<TH1F>("muonMult", "muon multiplicity"    ,  10, 0.,  10.);
  hists_["muonIso" ]=fs->make<TH1F>("muonIso" , "muon isolation"       ,  20, 0.,   1.);
  hists_["muonPt"  ]=fs->make<TH1F>("muonPt"  , "muon pt"              ,  30, 0., 150.);
  hists_["jetMult" ]=fs->make<TH1F>("jetMult" , "jet multiplicity"     ,  15, 0.,  15.);
  hists_["jet0Pt"  ]=fs->make<TH1F>("jet0Pt"  , "1. leading jet pt"    ,  50, 0., 250.);
  hists_["jet1Pt"  ]=fs->make<TH1F>("jet1Pt"  , "1. leading jet pt"    ,  50, 0., 250.);
  hists_["jet2Pt"  ]=fs->make<TH1F>("jet2Pt"  , "1. leading jet pt"    ,  50, 0., 200.);
  hists_["jet3Pt"  ]=fs->make<TH1F>("jet3Pt"  , "1. leading jet pt"    ,  50, 0., 200.);
  hists_["met"     ]=fs->make<TH1F>("met"     , "missing E_{T}"        ,  25, 0., 200.);

We have taken it from the file in the plugins directory of the PatExamples package. Just have a look into the file yourself to learn more about the exact implementation and histogram filling.

The fourth and final section of the file is dedicated to the process paths:

## ----------------------------------------------------------------
## Define the analysis paths: we define two selection paths to 
## monitor the cutflow according to the TopPAG reference selection
## for ICHEP 2010. All necessary object collections have been pro-
## duced in the cms.Path topObjectProduction before hand. The out-
## put report is switched on to get a quick overview of the number
## number of events after each selection step. 
## ----------------------------------------------------------------

## Switch output report on
process.options   = cms.untracked.PSet( wantSummary = cms.untracked.bool(True) )

## Define loose event selection path
process.looseEventSelection = cms.Path(
    process.step1      *
    process.step2      *
    process.step3b     *
    process.step4      *
    process.step5      *
    process.step6a     *
    process.step6b     *

## Define tight event selection path
process.tightEventSelection = cms.Path(
    process.monStart   * 
    process.step1      *
    process.monStep1   *         
    process.step2      *
    process.monStep2   * 
    process.step3a     *
    process.monStep3a  *     
    process.step4      *
    process.monStep4   *     
    process.step5      *
    process.monStep5   *     
    process.step6a     *
    process.monStep6a  *     
    process.step6b     *
    process.monStep6b  *     
    process.step6c     *
    process.monStep6c  *
    process.step7      *

ALERT! Note: You see that we switched the wantSummary option to True. We want to use it for our cutflow tables. We defined two paths as we want to follow a tight and a loose selection scenario. As after the object count filters whole events are discarded we cannot have the tight and the loose selection in one path, but nothing is wrong with having both paths in parallel. For simplicity reasons we fill monitor histograms only for the tight selection scenario up to selection step 7.

Once your process is finished you should see an output of this type in your shell:

TrigReport ---------- Modules in Path: topObjectProduction ------------
TrigReport  Trig Bit#    Visited     Passed     Failed      Error Name
TrigReport     1    0        100        100          0          0 goodJets
TrigReport     1    0        100        100          0          0 vetoElecs
TrigReport     1    0        100        100          0          0 vetoMuons
TrigReport     1    0        100        100          0          0 looseMuons
TrigReport     1    0        100        100          0          0 tightMuons

TrigReport ---------- Modules in Path: looseEventSelection ------------
TrigReport  Trig Bit#    Visited     Passed     Failed      Error Name
TrigReport     1    1        100         28         72          0 step1
TrigReport     1    1         28         28          0          0 step2
TrigReport     1    1         28         18         10          0 step3b
TrigReport     1    1         18         18          0          0 step4
TrigReport     1    1         18         15          3          0 step5
TrigReport     1    1         15         15          0          0 step6a
TrigReport     1    1         15         14          1          0 step6b
TrigReport     1    1         14         12          2          0 step6c

TrigReport ---------- Modules in Path: tightEventSelection ------------
TrigReport  Trig Bit#    Visited     Passed     Failed      Error Name
TrigReport     1    2        100        100          0          0 monStart
TrigReport     1    2        100         28         72          0 step1
TrigReport     1    2         28         28          0          0 monStep1
TrigReport     1    2         28         28          0          0 step2
TrigReport     1    2         28         28          0          0 monStep2
TrigReport     1    2         28         18         10          0 step3a
TrigReport     1    2         18         18          0          0 monStep3a
TrigReport     1    2         18         18          0          0 step4
TrigReport     1    2         18         18          0          0 monStep4
TrigReport     1    2         18         15          3          0 step5
TrigReport     1    2         15         15          0          0 monStep5
TrigReport     1    2         15         15          0          0 step6a
TrigReport     1    2         15         15          0          0 monStep6a
TrigReport     1    2         15         14          1          0 step6b
TrigReport     1    2         14         14          0          0 monStep6b
TrigReport     1    2         14         12          2          0 step6c
TrigReport     1    2         12         12          0          0 monStep6c
TrigReport     1    2         12          6          6          0 step7
TrigReport     1    2          6          6          0          0 monStep7

ALERT! Note: This example was only run on 100 events for demonstration purposes. You can easily find the paths back that we defined in our process:

  • topObjectProduction: to produce the selected object collections we used as input for the event selection.
  • looseEventSelection: the loose event selection scenario.
  • tightEventSelection: the tight event selection scenario.

Question Exercise a):
You can read the event numbers from the latter two path summaries when looking into the column passed. Run over all remaining samples and fill out the tables below:

Tight Selection Data Top Wjets Zjets QCD
step1 1206415       233807
step2 1194487       233739
step3a 10727       918
step4 10354       916
step5 10309       913
step6a 1907       361
step6b 372       46
step6c 81       5
step7 20       0
Weight Factor -        

Add the numbers you find for the following samples and steps in the tutorial form:

  • Ttbar, step 3a
  • Wjets, step 5
  • Zjets, step 6b

Save the histogram files as:

  • analyzePatTopSelection.root (data)
  • analyzePatTopSelection_ttbar.root
  • analyzePatTopSelection_wjets.root
  • analyzePatTopSelection_zjets.root
  • analyzePatTopSelection_qcd.root

ALERT! ATTENTION ALERT! The simulated events that have been used so far have been subject to a different pre-selection than the data. Therefore they are not fully comparable up to selection step 3a. In real life the agreement is much better. We will replaced the simulation by proper files in the next CMSSW update cycle.

Question Exercise b):
When finished with Exercise a) start root and run the macro indicated blelow:

[rwolf@lxplus231]~/scratch0/CMSSW_5_3_14/src% ls
PhysicsTools                     analyzePatTopSelection_ttbar.root  analyzePatTopSelection_zjets.root
analyzePatTopSelection_qcd.root  analyzePatTopSelection_wjets.root  patTuple.root
[rwolf@lxplus231]~/scratch0/CMSSW_5_3_14/src% root- l 
.x PhysicsTools/PatExamples/bin/monitorTopSelection.C+("yield", "Step1")
Info in : creating shared library /afs/
/usr/bin/ld: skipping incompatible /usr/lib64/ when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib64/libm.a when searching for -lm
/usr/bin/ld: skipping incompatible /usr/lib64/ when searching for -lc
/usr/bin/ld: skipping incompatible /usr/lib64/libc.a when searching for -lc

This should result in a set of plots of this kind:

Yield.png MuonPt.png

(left/upper) Event yield after each selection step. (right/lower) Transverse momentum of the leading muon after selection step 3a.

ALERT! Note: The macro monitorTopSelection.C expects all input files to present in the src directory of your working environment. It takes two arguments, histName indicating the physics quantity to be checked and selectionStep indicating the level at which to check this quantity. Both parameters have been set to default values for the beginning, resulting in the histogram shown above. You can check the following

histName Physics Quantity
yield yield plot
elecMult electron multiplicity
elecIso relIso for the leading electron
elecPt pt for the leading electron
muonMult muon multiplicity
muonIso relIso for the leading muon
muonPt pt for the leading muon
jetMult jet multipliciy
jet1Pt pt for the 1. leading jet
jet2Pt pt for the 2. leading jet
jet3Pt pt for the 3. leading jet
jet4Pt pt for the 4. leading jet
met missing transverse momentum (1)

(1) from default patMET, defined as the calorimeter based MET after type1 and muon corrections.

corresponding to the names that have been used for the histogram booking above. You may use the following selection steps Step1 till Step7 as second argument corresponding to the directories in the corresponding root histogram file. ( Indeed for yield the second argument selectionStep will be ignored. ) Have a look into one of the root histogram files to understand the file structure and a look into the implementation of the macro to see how it works. After all the macro is not too complicated.

ALERT! Note: You can find a prepared set of root histogram files, which you can copy into your working directory at


More complex analyses of top quarks

In the above example we followed a very of an analysis, the selection of events containing top quarks pairs. For high level analyses of top quark pair quantities the TopPAG supports an own toolkit:

The Top Quark Analysis Framework (TQAF) is a toolkit to facilitate the analysis of final states containing top quark pairs in the dileptonic, semi-leptonic and full hadronic decay channel. It is an integral part of CMSSW and build up on the Physics Analysis Toolkit (PAT). For more details on the TQAF have a look to the SWGuideTQAF. You will find the links to a set of examples on the use of the Top Quark Analysis Framework (TQAF) below. Each chapter will list the existing and planned tutorials for each corresponding decay channel fo the top antitop quark pair.

Review status

Reviewer/Editor and Date (copy from screen) Comments
LukasKreczko - 2016-07-07 CVS → Github
SamirGuragain - 11 June 2012 Went over the instructions.
RogerWolf - 7 July 2011 Update to 42X with some frictional losses.

Responsible: Volker Adler, Sebastian Naumann-Emme, and Kati Lassila Perini

Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng MuonPt.png r1 manage 12.4 K 2010-09-30 - 15:53 RogerWolf  
PNGpng TTbar.png r1 manage 34.1 K 2010-09-14 - 20:40 RogerWolf  
PNGpng Yield.png r1 manage 13.3 K 2010-09-30 - 15:53 RogerWolf  
Cascading Style Sheet filecss tutorial.css r1 manage 0.2 K 2010-09-14 - 22:14 RogerWolf  
Edit | Attach | Watch | Print version | History: r53 < r52 < r51 < r50 < r49 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r53 - 2016-07-07 - LukasKreczko
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    CMSPublic All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback