WARNING: This twiki is outdated , please refer to the main PAT twiki SWGuidePAT

PAT - Layer 2

Complete: 1


The purpose of the PAT Layer 2 is to provide hypothesis-specific interfaces to the PAT. The advantages of this are manyfold:

  • Objects that use the PAT Layer 2 will have a similar "feel" to the users.
  • Objects that use the PAT Layer 2 will be able to be automatically plotted by histogram utilities like the StarterKit
  • Users can easily construct their own personal event hypotheses using the PAT Layer 2 functionality.


The design philosophy of the PAT Layer 2 was to provide generic "role" assignments to the user. That is, the event hypothesis should make intuitive sense and the user can assign specific labels to each of the daughters in a hypothesis. For instance, one event hypothesis could be

Z -> muon + muon

The roles would be trivial in this case, simply two muons, and the output (the Z, constructed from the two muon roles):

muon1 : muon
muon2 : muon
Z = muon1 + muon2

We can further build more complicated event hypotheses like

H -> (Z -> muon + muon) + (Z -> electron + electron)
The roles in this case would be the two muons, two electrons, the two Z's constructed from those leptons, and the Higgs constructed from those Z bosons.
muon1 : muon
muon2 : muon
electron1 : electron
electron2 : electron
Z1 = muon1 + muon2
Z2 = electron1 + electron2
H = Z1 + Z2

The user should be able to access the daughters by giving the string of the roles. This allows for more intuitive data access and more specific "human" control over the construction of the event hypothesis.

The PAT Layer 2 implements the role structure with two separate options available to the user.

  • Flat Event Hypothesis
  • Hierarchical Event Hypothesis

We now discuss these each in turn.

Flat Event Hypothesis

The flat event hypothesis declares the event hypothesis without automatically structuring the constituents. Therefore, the hypothesis shown above is precisely the way that the hypothesis is formed in the event. Each member is basically a "string to object map", which will input a string and give back the item corresponding to it. The simplest accessor in the interface is as follows:

const CandRefType & get(const std::string &role, int index=0) const ;

Here, we see that we are accessing the candidate by the role name, as well as an index should that role be part of a vector. This allows for accessing the "jets" in a "Z + jets" or a "ttbar + jets" event hypothesis.

There are many ways to navigate the event hypothesis here, including "loopers" which will loop over particles of the same role, or similar roles (as defined by regular expressions):

CandLooper loop(const std::string &roleRegexp) const;

The looper is able to access particles by regular expressions, and can navigate through those candidates. So, for instance, if your roles are named muon1 and muon2, you can get all the muons by

Looper<Muon> looper = hyp.loop("muon[12]");

while( !looper() ) {
   const Muon & mu = *looper;
   fill( mu.pt() );

Hierarchical Event Hypothesis

The hierarchical event hypothesis is based on NamedCompositeCandidates. Instead of directly placing all objects in a flat structure, it instead stores them hierarchically as a decay chain. So, in the example above, the data storage would be

H -> (Z1 -> muon1 + muon2) + (Z2 -> electron1 + electron2)
The advantage of the hierarchical structure is that the nodes of the hypothesis are all reco::Candidates. There is no need to have a secondary access to get at the Candidate, because it is simply stored as the reco::Candidates themselves. For true decays, a hierarchical structure is also somewhat more intuitive and allows for easy generation of multiple hierarchies with little to no effort.

The way to construct such an event hypothesis would be as follows:

      Muon & mu1 = ..., & mu2 = ...;
      Electron & ele1 = ..., & ele2 = ...;
      NamedCompositeCandidate Z1("Z1");
      Z1.addDaughter( mu1, "muon1");
      Z1.addDaughter( mu2, "muon2");
      NamedCompositeCandidate Z2("Z2");
      Z2.addDaughter( ele1, "electron1");
      Z2.addDaughter( ele2, "electron2");

      NamedCompositeCandidate H("H");
      H.addDaughter( Z1, "Z1");
      H.addDaughter( Z2, "Z2"); 

To access the daughters, one can do

      const Candidate * Z1 = H.daughter("Z1");

Since these are based on =reco::CompositeCandidates=, a host of tools are at the fingers of the user. For instance, one can create a shallow clone candidate" and add it to the event hypothesis to avoid making a copy and thereby saving space and time. The user also has the full suite of Candidate Utilities developed by the Physics Tools group available to them. Therefore the event hypothesis can be manipulated, selected upon, combined into other hypotheses, automatically plotted, streamed to the event record, and many other things.

Relative Advantages and Disadvantages.

  • Flat Event Hypothesis
    • Advantages:
      • Simple to examine objects with the same type.
      • Simple to loop over the entire event hypothesis.
      • Able to naturally handle cases like Z + jets which are not strict decays.
    • Disadvantages:
      • No way to combine nodes in the hypothesis automatically.
      • No tools available automatically (such as selectors, etc).
      • The user must know what the hierarchy is in their brain, there is no way to glean this from the event hypothesis itself.
  • Hierarchical Event Hypothesis
    • Advantages:
      • Trivial to combine nodes automatically.
      • Has access to full suite of Candidate manipulations.
      • More natural to handle "true" decays.
    • Disadvantages:
      • Does not naturally handle cases like Z + jets... the user cannot add the "plus jets" part into the hypothesis without making unphysical nodes (there is nothing special about the parent of the Z and the jets).
      • Difficult to loop over single types (i.e. no regular expression looping mechanism).
      • To access nodes, must loop through hierarchy.

Ultimately your analysis will be better served by one or the other of these. We provide both as alternatives to the user, who can decide which is more appropriate to their analysis.


Flat Event Hypothesis

Coming soon!

Hierarchical Event Hypothesis

Using Candidate Combiners

A functional code snippet to use the PAT Layer 1 objects in an event hypothesis is

  ### H->ZZ ###
  module zToMuMu = NamedCandViewShallowCloneCombiner {
    string decay = "selectedLayer1Muons@+ selectedLayer1Muons@-"
    string cut = "0.0 < mass < 20000.0"
    string name = "zToMuMu"
    vstring roles = { 'muon1', 'muon2' }

  module hToZZ = NamedCandViewCombiner {
    string decay = "zToMuMu zToMuMu"
    string cut = "0.0 < mass < 20000.0"
    string name = "hToZZ"
    vstring roles = { 'Z1', 'Z2' }

The first module will create Z->mu + mu candidates from ShallowCloneCandidates of PAT Layer 1 muons (which are input in a View), and output a vector. The second module will then use the output of the first to create Higgs candidates from H -> Z1 + Z1. These will be straight copies of the Z's from the first, since they are transient and can be safely discarded. To store the entire hierarchy, place the following snippet in your configuration file:

  replace patEventContent.outputCommands += {
    "keep *_hToZZ_*_*"

This will store the entire hierarchy of all the Higgs candidates in the event.

The StarterKit has a full example of using this example here.

Hierarchical Event Hypothesis in TQAF

The hierarchical event hypothesis is fully explointed and implemented in the complex environment of top analyses with help of the TQAF. For more information on the implementation have a look to the SWGuideTQAFClasses and the SWGuideTQAFLayer2 description. For a step by step tutorial how to implement new event hypotheses with the help of TQAF and how to use and exploit them within the full framework and FWLite have a look to the SWGuideTQAFTutorial

Using pre-existing Layer 2 in TQAF

It is also possible to modify existing event hypothesis, such as those in the TQAF Layer 2. As a prototype we have modified the class TtSemiEvtSolution to include the following event hypothesis:

  reco::NamedCompositeCandidate recoHyp_;

This is filled with a function in the source file:

void TtSemiEvtSolution::setupHyp() 

  AddFourMomenta addFourMomenta;


  // Setup transient references
  reco::NamedCompositeCandidate recHadt;
  reco::NamedCompositeCandidate recLept;
  reco::NamedCompositeCandidate recHadW;
  reco::NamedCompositeCandidate recLepW;

  // Get refs to leaf nodes
  reco::ShallowCloneCandidate hadp( reco::CandidateBaseRef( hadp_ ), hadp_->charge(), hadp_->p4(), hadp_->vertex() );
  reco::ShallowCloneCandidate hadq( reco::CandidateBaseRef( hadq_ ), hadq_->charge(), hadq_->p4(), hadq_->vertex() );
  reco::ShallowCloneCandidate hadb( reco::CandidateBaseRef( hadb_ ), hadb_->charge(), hadb_->p4(), hadb_->vertex() );
  reco::ShallowCloneCandidate lepb( reco::CandidateBaseRef( lepb_ ), lepb_->charge(), lepb_->p4(), lepb_->vertex() );

  reco::ShallowCloneCandidate neutrino( reco::CandidateBaseRef( neutrino_ ), neutrino_->charge(), neutrino_->p4(), neutrino_->vertex() );

  recHadW.addDaughter( hadp,    "hadp" );
  recHadW.addDaughter( hadq,    "hadq" );

  addFourMomenta.set( recHadW );

  recHadt.addDaughter( hadb,    "hadb" );
  recHadt.addDaughter( recHadW, "hadW" );

  addFourMomenta.set( recHadt );
  recLepW.addDaughter( neutrino,"neutrino" );
  if ( getDecay() == "electron" ) {
    reco::ShallowCloneCandidate electron ( reco::CandidateBaseRef( electron_), electron_->charge(), electron_->p4(), electron_->vertex() );
    recLepW.addDaughter ( electron, "electron" );
  } else if ( getDecay() == "muon" ) {
    reco::ShallowCloneCandidate muon ( reco::CandidateBaseRef( muon_ ), muon_->charge(),  muon_->p4(), muon_->vertex() );
    recLepW.addDaughter ( muon, "muon" );

  addFourMomenta.set( recLepW );

  recLept.addDaughter( lepb,    "lepb" );
  recLept.addDaughter( recLepW,    "lepW" );

  addFourMomenta.set( recLept );

  recoHyp_.addDaughter( recHadt, "hadt" );
  recoHyp_.addDaughter( recLept, "lept" );

  addFourMomenta.set( recoHyp_ );

This function creates ShallowCloneCandidates out of the objects of interest and creates a ttbar event hierarchy. This can be fed into plotting utilities like the StarterKit. A fully worked example from the StarterKit is shown here.

Reviewer/Editor and Date Comments
SalvatoreRappoccio - 08 May 2008 First layout
Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng PAT-objects-s.png r2 r1 manage 153.9 K 2008-04-24 - 18:12 FredericRonga Illustration of the PAT objects' hierarchy
PDFpdf PAT-objects.pdf r2 r1 manage 25.2 K 2008-04-24 - 18:12 FredericRonga Illustration of the PAT objects' hierarchy (PDF file)
Edit | Attach | Watch | Print version | History: r5 < r4 < r3 < r2 < r1 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r5 - 2009-09-19 - SudhirMalik
    • 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-2022 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback