Code overview of the StarterKit

In this section, we examine the code of the Starter Kit in detail.. We will examine the three plugin modules in the StarterKit: PatAnalyzerSkeleton, PatAnalyzerKit, and CompositeKit.


We first examine the PatAnalyzerSkeleton. The intention of this plugin is to demonstrate the minimal steps needed to do a PAT analysis.

Config file

The configuration file is

We first import the configuration for CMS into python with the command:

# Import configurations
import FWCore.ParameterSet.Config as cms

We then define a process called "StarterKit" that will do our processing as:

# set up process
process = cms.Process("StarterKit")

Next, we initialize the message logger and set up a usable amount of error and information printing, as well as requesting a PAT output summary, with this:

# initialize MessageLogger and output report
process.MessageLogger.cerr.threshold = 'INFO'
process.MessageLogger.cerr.INFO = cms.untracked.PSet(
    default          = cms.untracked.PSet( limit = cms.untracked.int32(0)  ),
    PATLayer0Summary = cms.untracked.PSet( limit = cms.untracked.int32(-1) )
process.options   = cms.untracked.PSet( wantSummary = cms.untracked.bool(True) )

Next we load the geometry we desire, in this case STARTUP_V4.

# Load geometry
process.GlobalTag.globaltag = cms.string('STARTUP_V4::All')

Now we define which input files to run over:

# this defines the input files
from CMS.PhysicsTools.StarterKit.RecoInput_cfi import *

# this inputs the input files from the previous function
process.source = RecoInput()

Here is where we set the number of events:

# set the number of events
process.maxEvents = cms.untracked.PSet(
    input = cms.untracked.int32(200)

Next we define the two PAT sequences... Layer 0 and Layer 1. You can find details about them here:

# input pat sequences

Next we set up our skeleton analyzer:

# input pat skeleton analyzer sequence

This is where we talk, to TFileService which manages the histograms:

# talk to TFileService for output histograms
process.TFileService = cms.Service("TFileService",
    fileName = cms.string('PatAnalyzerSkeletonHistos.root')

Now we define the processing path, which consists of just three modules, PAT Layer 0, PAT Layer 1, and the analyzer skeleton:

# define path 'p': PAT Layer 0, PAT Layer 1, and the analyzer
process.p = cms.Path(process.patLayer0*

Here we tell the output module which classes to keep, in this case the PAT Layer 1 objects.

# load the pat layer 1 event content

# setup event content: drop everything before PAT
process.patEventContent = cms.PSet(
    outputCommands = cms.untracked.vstring('drop *')

# extend event content to include PAT objects

# define output event selection to be that which satisfies 'p'
process.patEventSelection = cms.PSet(
    SelectEvents = cms.untracked.PSet(
        SelectEvents = cms.vstring('p')

Finally, we talk to the output module itself, tell it what path to process, tell it what content to keep, and where to put the output file.

# talk to output module
process.out = cms.OutputModule("PoolOutputModule",
    verbose = cms.untracked.bool(False),
    fileName = cms.untracked.string('PatAnalyzerSkeletonSkim.root')

# define output path
process.outpath = cms.EndPath(process.out)

This is the end of the first configuration file. We will now examine the PatAnalyzerSkeleton module configuration.

Module configuraiton

The module configuration file is here:

In this case it is extremely simple, it just defines the input tags to use for the PAT objects:

patAnalyzerSkeleton = cms.EDAnalyzer("PatAnalyzerSkeleton",
    electronTag = cms.untracked.InputTag("selectedLayer1Electrons"),
    tauTag = cms.untracked.InputTag("selectedLayer1Taus"),
    muonTag = cms.untracked.InputTag("selectedLayer1Muons"),
    jetTag = cms.untracked.InputTag("selectedLayer1Jets"),
    photonTag = cms.untracked.InputTag("selectedLayer1Photons"),
    metTag = cms.untracked.InputTag("selectedLayer1METs")

Now we will examine the PatAnalyzerSkeleton plugin itself to get a sense for what is being done.

Plugin file

The PatAnalyzerSkeleton plugin is very simple... it just books some histograms, runs over the PAT content, fills the histograms, and writes the histograms. The files are here:

The relevant snippets of code are shown here.

This is where we book histograms in the constructor:

  edm::Service<TFileService> fs;

  histocontainer_["njets"]=fs->make<TH1D>("njets","jet multiplicity for jets with p_{T} > 50 GeV/c",10,0,10);
  histocontainer_["nelectrons"]=fs->make<TH1D>("nelectrons","electron multiplicity",10,0,10);
  histocontainer_["ntaus"]=fs->make<TH1D>("ntaus","tau multiplicity",10,0,10);
  histocontainer_["nphotons"]=fs->make<TH1D>("nphotons","photon multiplicity",10,0,10);
  histocontainer_["nmuons"]=fs->make<TH1D>("nmuons","muon multiplicity",10,0,10);

This is where the handles to the PAT objects are obtained in "analyze":

   edm::Handle<edm::View<pat::Muon> > muonHandle;
   edm::View<pat::Muon> muons = *muonHandle;
   edm::Handle<edm::View<pat::Jet> > jetHandle;
   edm::View<pat::Jet> jets = *jetHandle;

   edm::Handle<edm::View<pat::Electron> > electronHandle;
   edm::View<pat::Electron> electrons = *electronHandle;

   edm::Handle<edm::View<pat::MET> > metHandle;
   edm::View<pat::MET> mets = *metHandle;

   edm::Handle<edm::View<pat::Photon> > phoHandle;
   edm::View<pat::Photon> photons = *phoHandle;

   edm::Handle<edm::View<pat::Tau> > tauHandle;
   edm::View<pat::Tau> taus = *tauHandle;

And finally, this is where the histograms are filled, also in "analyze":

   size_t njetscounter=0;
   for(edm::View<pat::Jet>::const_iterator jet_iter = jets.begin(); jet_iter!=jets.end(); ++jet_iter){

That's it! This is the simplest analysis you can do with the PAT. This concludes the first example, the PatAnalyzerSkeleton.


The PatAnalyzerKit is designed to be more of a comprehensive snapshot of the event than PatAnalyzerSkeleton. It will utilize PatKitHelper to histogram all of the objects in the event. These histograms will include four-vector information, matching and object variables for each physics object, and has the capability of automatically producing EDNtuples with the output. We will examine the changes in the python configuration file that are not present in PatAnalyzerSkeleton so as to avoid repetition.

Config file

The configuration file for the PatAnalyzerKitDemo is here:

The differences between this and the PatAnalyzerSkeleton are shown next.

First, we have the module itself:

# input pat analyzer sequence

Next, we have the inclusion of the EDNtuple objects written by the PatAnalyzerKit:

# extend event content to include pat analyzer kit objects from EDNtuple
process.patLayer1EventContent.outputCommands.extend(['keep *_patAnalyzerKit_*_*'])

And lastly, we have the different path:

# define path 'p': PAT Layer 0, PAT Layer 1, and the analyzer
process.p = cms.Path(process.patLayer0*

We now turn to the module configuration.

Module configuration

The PatAnalyzerKit module configuration is here:

First we define a nice python function to give us parameter sets for histogramming axes:

from CMS.PhysicsTools.StarterKit.kinAxis_cfi  import *

Next we have the module itself.

patAnalyzerKit = cms.EDProducer("PatAnalyzerKit",

This is a list of which variables to ntuplize:

    ntuplize = cms.string('all'),

This is a string list of the histograms to enable or disable:

    enable = cms.string(''),
    disable = cms.string(''),

Here is the input tags, like PatAnalyzerSkeleton:

    electronSrc = cms.InputTag("selectedLayer1Electrons"),
    tauSrc = cms.InputTag("selectedLayer1Taus"),
    muonSrc = cms.InputTag("selectedLayer1Muons"),
    jetSrc = cms.InputTag("selectedLayer1Jets"),
    photonSrc = cms.InputTag("selectedLayer1Photons"),
    METSrc = cms.InputTag("selectedLayer1METs"),

And here are the kinematic axis limits. The numbers are min pt, max pt, min mass, and max mass:

    muonAxis     = kinAxis(0, 200, 0, 200),
    electronAxis = kinAxis(0, 200, 0, 200),
    tauAxis      = kinAxis(0, 200, 0, 200),
    jetAxis      = kinAxis(0, 200, 0, 200),
    METAxis      = kinAxis(0, 200, 0, 200),
    photonAxis   = kinAxis(0, 200, 0, 200),
    trackAxis    = kinAxis(0, 200, 0, 200)

We now turn to the plugin file itself:

Plugin file

The plugin files are here:

The workhorse for this plugin is in the class definition for the EDProducer here:

  // The main sub-object which does the real work
  pat::PatKitHelper    helper_;

This is found here:

The way to use this is as follows.

  • Pass the configuration to the helper and book the histograms and ntuple:
PatAnalyzerKit::PatAnalyzerKit(const edm::ParameterSet& iConfig)

  • Next, in "produce", get the handles:
  helper_.getHandles( evt,

  • Finally, fill the histograms in "produce". This will also produce ntuples:
  helper_.fillHistograms( evt,

That's it! All the plethora of histograms from the StarterKit are now being plotted. If you wish to include these in your own module, it's a simple as these three steps.

We now show how the StarterKit can handle CompositeCandidates.


The module to handle automatic plotting of CompositeCandidates is CompositeKit. CompositeCandidates can be examined here:

The advantage of using these is to create different event hypotheses as described here:

The StarterKit can handle a collection of any CompositeCandidates and will make plots of the relevant kinematic quantities.

Config file

The config file in question is:

In this example we use the CandidateCombiner functions as described here:

and the selectors as described here:

We attempt to make H->ZZ->muons candidates using the combinatoric tools. We then pass the CandidateCollection of candidates from that combinatoric tools to the CompositeKit.

The relevant changes from the other two examples are here:

# produce Z to mu mu candidates
process.zToMuMu = cms.EDProducer("CandViewShallowCloneCombiner",
    decay = cms.string('selectedLayer1Muons@+ selectedLayer1Muons@-'),
    cut = cms.string('0.0 < mass < 20000.0'),
    name = cms.string('zToMuMu'),
    roles = cms.vstring('muon1', 'muon2')

# produce Higgs to Z Z candidates
process.hToZZ = cms.EDProducer("CandViewCombiner",
    decay = cms.string('zToMuMu zToMuMu'),
    cut = cms.string('0.0 < mass < 20000.0'),
    name = cms.string('hToZZ'),
    roles = cms.vstring('Z1', 'Z2')

# require at least one higgs to zz candidate
process.compositeFilter = cms.EDFilter("CandViewCountFilter",
    src = cms.InputTag("hToZZ"),
    minNumber = cms.uint32(1)


# define path 'p': PAT Layer 0, PAT Layer 1, and the analyzer
process.p = cms.Path(process.patLayer0*


process.patLayer1EventContent.outputCommands.extend(['keep *_hToZZ_*_*'])

Module configuration

The module configuration in this case is:

In its entirety, this is:

import FWCore.ParameterSet.Config as cms
from CMS.PhysicsTools.StarterKit.kinAxis_cfi  import *

CompositeKitDemo = cms.EDProducer("CompositeKit",
    description = cms.string('Higgs to Z + Z'),
    outputTextName = cms.string('CompositeKitKit_output.txt'),
    enable = cms.string(''),
    disable = cms.string(''),
    src = cms.InputTag("hToZZ"),
    ntuplize = cms.string('all'),
    electronSrc = cms.InputTag("selectedLayer1Electrons"),
    tauSrc = cms.InputTag("selectedLayer1Taus"),
    muonSrc = cms.InputTag("selectedLayer1Muons"),
    jetSrc = cms.InputTag("selectedLayer1Jets"),
    photonSrc = cms.InputTag("selectedLayer1Photons"),
    METSrc = cms.InputTag("selectedLayer1METs"),
    muonAxis     = kinAxis(0, 200, 0, 200),
    electronAxis = kinAxis(0, 200, 0, 200),
    tauAxis      = kinAxis(0, 200, 0, 200),
    jetAxis      = kinAxis(0, 200, 0, 200),
    METAxis      = kinAxis(0, 200, 0, 200),
    photonAxis   = kinAxis(0, 200, 0, 200),
    trackAxis    = kinAxis(0, 200, 0, 200),
    compositeAxis= kinAxis(0, 100, 0, 300)

The important input is "src", which inputs the CandidateCollection of CompositeCandidates in question.

We now examine the plugin itself to see how these are dealt with.

Plugin file

The plugin file is

This will also have an instance of PatKitHelper to make kinematic plots of the variables in the event, but it also contains

  pat::HistoComposite *      compositeCandHist_;

HistoComposite will drill down a hierarchical CompositeCandidate and make plots based on the leaf types. If it is another CompositeCandidate, only four-momenta are plotted. If the leaf is a specific detector object (for instance, Muon), it will plot the relevant distributions for those variables. One only needs pass the CompositeCandidate to the HistoComposite as

  iEvent.getByLabel(src_,   compositeCandHandle_ );

  if ( compositeCandHandle_->size() > 0 ) {
    vector<reco::CompositeCandidate>::const_iterator i = compositeCandHandle_->begin(),
      iend = compositeCandHandle_->end();
    for ( ; i != iend; ++i ) {
      compositeCandHist_->fill( *i );

-- SalvatoreRRappoccio - 04 Aug 2008

Topic attachments
I Attachment History Action Size Date Who Comment
JPEGjpg pat_logo.jpg r1 manage 3.4 K 2008-08-04 - 22:24 SalvatoreRRappoccio  
Edit | Attach | Watch | Print version | History: r4 < r3 < r2 < r1 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r4 - 2009-05-12 - RogerWolf
    • 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