CMS 3D CMS Logo

Enumerations | Functions

/data/git/CMSSW_5_3_11_patch5/src/PhysicsTools/FWLite/examples/secvtxMassTemplates.cc File Reference

#include "DataFormats/FWLite/interface/Handle.h"
#include "DataFormats/PatCandidates/interface/Jet.h"
#include "DataFormats/PatCandidates/interface/Muon.h"
#include "DataFormats/HepMCCandidate/interface/FlavorHistory.h"
#include "DataFormats/HepMCCandidate/interface/GenParticle.h"
#include "Math/GenVector/PxPyPzM4D.h"
#include "PhysicsTools/FWLite/interface/EventContainer.h"
#include "PhysicsTools/FWLite/interface/CommandLineParser.h"
#include "TROOT.h"
#include "TH2F.h"

Go to the source code of this file.

Enumerations

enum  { kNormalMode, kVqqMode, kLFMode, kWcMode }

Functions

void bookHistograms (fwlite::EventContainer &eventCont)
bool calcSampleName (fwlite::EventContainer &eventCont, string &sampleName)
int main (int argc, char *argv[])
void outputNameTagFunc (string &tag)

Enumeration Type Documentation

anonymous enum
Enumerator:
kNormalMode 
kVqqMode 
kLFMode 
kWcMode 

Definition at line 21 of file secvtxMassTemplates.cc.


Function Documentation

void bookHistograms ( fwlite::EventContainer eventCont)

Definition at line 293 of file secvtxMassTemplates.cc.

References fwlite::EventContainer::add(), optutl::VariableMapCont::integerValue(), metsig::jet, kLFMode, kVqqMode, geometryXMLtoCSV::parser, fwlite::EventContainer::parser(), optutl::VariableMapCont::stringValue(), and GlobalPosition_Frontier_DevDB_cff::tag.

Referenced by L1ExtraDQM::beginRun(), and main().

{
   // First, come up with all possible base   //
   // names (E.g., Wbb, Wb2, etc.).           //
   CommandLineParser &parser = eventCont.parser();
   CommandLineParser::SVec baseNameVec;
   CommandLineParser::SVec beginningVec, endingVec;
   switch ( parser.integerValue ("mode") )
   {
      case kVqqMode:
         // We want Wbb, Wb2, .., Zbb, ..  In this case, we completely
         // ignore the sampleName that was passed in.
         // Starts with
         beginningVec.push_back ("X");
         beginningVec.push_back ("W");
         beginningVec.push_back ("Z");
         // Ends with
         endingVec.push_back( "bb" );
         endingVec.push_back( "b2" );
         endingVec.push_back( "cc" );
         endingVec.push_back( "c2" );
         for (CommandLineParser::SVecConstIter outerIter = beginningVec.begin();
              beginningVec.end() != outerIter;
              ++outerIter)
         {
            for (CommandLineParser::SVecConstIter innerIter = endingVec.begin();
                 endingVec.end() != innerIter;
                 ++innerIter)
            {
               baseNameVec.push_back( *outerIter + *innerIter);
            } // for innerIter
         } // for outerIter
         break;
      case kLFMode:
         // just like the default case, except that we do have some
         // heavy flavor pieces here, too.
         baseNameVec.push_back(parser.stringValue ("sampleName") + "b3");
         baseNameVec.push_back(parser.stringValue ("sampleName") + "c3");
         // no break because to add just the name as well
      default:
         // We just want to use the sample name as it was given to us.
         baseNameVec.push_back(parser.stringValue ("sampleName"));
   } // for switch

   // Now the different tagging endings. //
   CommandLineParser::SVec singleTagEndingVec, doubleTagEndingVec;
   singleTagEndingVec.push_back ("_b");
   singleTagEndingVec.push_back ("_c");
   singleTagEndingVec.push_back ("_q");
   doubleTagEndingVec.push_back ("_bb");
   doubleTagEndingVec.push_back ("_cc");
   doubleTagEndingVec.push_back ("_qq");
   doubleTagEndingVec.push_back ("_bc");
   doubleTagEndingVec.push_back ("_bq");
   doubleTagEndingVec.push_back ("_cq");

   // Finally, let's put it all together. //
   for (CommandLineParser::SVecConstIter baseIter = baseNameVec.begin();
        baseNameVec.end() != baseIter;
        ++baseIter)
   {
      // For each flavor, one jet/tag counting histogram. //
      TString histName = *baseIter + "_jettag";
      eventCont.add( new TH2F( histName, histName, 
                               6, -0.5, 5.5,
                               3, -0.5, 2.5) );
      for (int jet = 1; jet <= 5; ++jet)
      {
         for (int tag = 1; tag <= 2; ++tag)
         {
            // For each jet/tag, a single secvtx mass //
            if (tag > jet) continue;
            histName = *baseIter + Form ("_secvtxMass_%dj_%dt", jet, tag);
            eventCont.add( new TH1F( histName, histName, 40, 0, 10) );
            CommandLineParser::SVec *vecPtr = &singleTagEndingVec;
            if (2 == tag)
            {
               vecPtr = &doubleTagEndingVec;
            } // double tag
            for (CommandLineParser::SVecConstIter tagIter = vecPtr->begin();
                 vecPtr->end() != tagIter;
                 ++tagIter)
            {
               // And different secvtx mass for each tag ending. //
               histName = *baseIter + Form ("_secvtxMass_%dj_%dt", jet, tag)
                  + *tagIter;
               eventCont.add( new TH1F( histName, histName, 40, 0, 10) );
            } // for tagIter
         } // for tag
      } // for jet
   } // for baseIter
}
bool calcSampleName ( fwlite::EventContainer eventCont,
string &  sampleName 
)

Definition at line 399 of file secvtxMassTemplates.cc.

References abs, fwlite::Handle< T >::getByLabel(), optutl::VariableMapCont::integerValue(), fwlite::Handle< T >::isValid(), kLFMode, kNormalMode, kWcMode, mode, geometryXMLtoCSV::parser, fwlite::EventContainer::parser(), and optutl::VariableMapCont::stringValue().

Referenced by main().

{
   // calculate sample name
   CommandLineParser &parser = eventCont.parser();
   sampleName = parser.stringValue  ("sampleName");
   int mode   = parser.integerValue ("mode");

   // Normal Mode //
   if (kNormalMode == mode)
   {
      // all we want is the sample name, so in this case we're done.
      return true;
   }
   // Get the heavy flavor category
   fwlite::Handle< unsigned int > heavyFlavorCategory;
   heavyFlavorCategory.getByLabel (eventCont, "flavorHistoryFilter");
   assert ( heavyFlavorCategory.isValid() );
   int HFcat = (*heavyFlavorCategory);

   // Light Flavor Mode //
   if (kLFMode == mode)
   {
      // Wqq
      if (5 == HFcat)
      {
         sampleName += "b3";
      } else if (6 == HFcat)
      {
         sampleName += "c3";
      } else if (11 != HFcat)
      {
         // skip this event
         return false;
      } // else if ! 11
      return true;
   }

   // Wc Mode //
   if (kWcMode == mode)
   {
      // Wc
      if (4 != HFcat)
      {
         // skip this event
         return false;
      } // if not Wc
      return true;
   } // else if Wc

   // Vqq Mode //
   // MadGraph (at least as CMS has implemented it) has this _lovely_
   // feature that if the W or Z is far enough off-shell, it erases
   // the W or Z from the event record.  This means that in some
   // number of cases, we won't be able to tell whether this is a W or
   // Z event by looking for a W or Z in the GenParticle collection.
   // (We'll eventually have to be more clever).
   sampleName = "X";
   fwlite::Handle< vector< reco::GenParticle > > genParticleCollection;
   genParticleCollection.getByLabel (eventCont, "genParticles");
   assert ( genParticleCollection.isValid() );
   // We don't know if it is a W, a Z, or neither
   // Iterate over genParticles
   const vector< reco::GenParticle>::const_iterator 
      kGenPartEnd = genParticleCollection->end();
   for (vector< reco::GenParticle>::const_iterator gpIter =
           genParticleCollection->begin(); 
        gpIter != kGenPartEnd; ++gpIter ) 
   {
      if (gpIter->status() == 3 && std::abs(gpIter->pdgId()) == 23)
      {
         sampleName = "Z";
         break;
      }
      if (gpIter->status() == 3 && std::abs(gpIter->pdgId()) == 24)
      {
         sampleName = "W";
         break;
      }
   } // for  gpIter
   switch (HFcat)
   {
      // from:
      // https://twiki.cern.ch/twiki/bin/viewauth/CMS/SWGuideFlavorHistory
      //  1. W+bb with >= 2 jets from the ME (dr > 0.5)
      //  2. W+b or W+bb with 1 jet from the ME
      //  3. W+cc from the ME (dr > 0.5)
      //  4. W+c or W+cc with 1 jet from the ME
      //  5. W+bb with 1 jet from the parton shower (dr == 0.0)
      //  6. W+cc with 1 jet from the parton shower (dr == 0.0)
      //  7. W+bb with >= 2 partons but 1 jet from the ME (dr == 0.0)
      //  8. W+cc with >= 2 partons but 1 jet from the ME (dr == 0.0)
      //  9. W+bb with >= 2 partons but 2 jets from the PS (dr > 0.5)
      // 10. W+cc with >= 2 partons but 2 jets from the PS (dr > 0.5)
      // 11. Veto of all the previous (W+ light jets)
      case 1:
         sampleName += "bb";
         break;
      case 2:
         // Sometimes this is referred to as 'b' (e.g., 'Wb'), but I
         // am using the suffix '2' to keep this case clear for when
         // we have charm (see below).
         sampleName += "b2";
         break; 
      case 3:
         sampleName += "cc";
         break;
      case 4:
         // We want to keep this case clear from real W + single charm
         // produced (as opposed to two charm quarks produced and one
         // goes down the beampipe), so we use 'c2' instead of 'c'.
         sampleName += "c2";
         break;
      default:
         // we don't want the rest of the cases.  Return an empty
         // string so we know.
         return false;
   } // switch HFcat
   return true;
}
int main ( int  argc,
char *  argv[] 
)

Definition at line 53 of file secvtxMassTemplates.cc.

References abs, optutl::VariableMapCont::addOption(), fwlite::EventContainer::atEnd(), bookHistograms(), calcSampleName(), fwlite::Handle< T >::getByLabel(), fwlite::EventContainer::hist(), fwlite::Handle< T >::isValid(), min, reco::SecondaryVertexTagInfo::nVertices(), optutl::CommandLineParser::parseArguments(), geometryXMLtoCSV::parser, reco::SecondaryVertexTagInfo::secondaryVertex(), optutl::VariableMapCont::stringValue(), and fwlite::EventContainer::toBegin().

{
   // ////////////////////////// //
   // // Command Line Options // //
   // ////////////////////////// //

   // Tell people what this analysis code does and setup default options.
   CommandLineParser parser ("Creates SecVtx Mass templates");

   // Add any command line options you would like here //
   parser.addOption ("mode",         CommandLineParser::kInteger, 
                     "Normal(0), VQQ(1), LF(2), Wc(3)", 
                     0);   
   parser.addOption ("sampleName",   CommandLineParser::kString, 
                     "Sample name (e.g., top, Wqq, etc.)");   

   parser.stringValue ("outputFile") = "jetPt"; // .root added automatically

   // Parse the command line arguments
   parser.parseArguments (argc, argv);

   // //////////////////////////// //
   // // Create Event Container // //
   // //////////////////////////// //

   // This object 'eventCont' is used both to get all information from the
   // eventCont as well as to store histograms, etc.
   // Parse the command line arguments
   parser.parseArguments (argc, argv);

   // //////////////////////////// //
   // // Create Event Container // //
   // //////////////////////////// //

   fwlite::EventContainer eventCont (parser);

   // ////////////////////////////////// //
   // //         Begin Run            // //
   // // (e.g., book histograms, etc) // //
   // ////////////////////////////////// //

   // Setup a style
   gROOT->SetStyle ("Plain");

   // Book those histograms!
   bookHistograms (eventCont);

   // //////////////// //
   // // Event Loop // //
   // //////////////// //

   for (eventCont.toBegin(); !eventCont.atEnd(); ++eventCont) 
   {
      // Take What We Need From Event //
      fwlite::Handle< vector< pat::Jet > > jetCollection;
      jetCollection.getByLabel (eventCont, "selectedLayer1Jets");
      assert ( jetCollection.isValid() );
                                                
      fwlite::Handle< vector< pat::Muon > > goodMuonCollection;
      goodMuonCollection.getByLabel (eventCont, "goodLeptons");
      assert ( goodMuonCollection.isValid() );
                        
      // If we don't have any good leptons, don't bother
      if (! goodMuonCollection->size() )
      {
         continue;
      }

      // get the sample name for this event
      string sampleName;
      if ( ! calcSampleName (eventCont, sampleName) )
      {
         // We don't want this one.
         continue;
      }

      // Tagged Jets and Flavor Separator //
      int numBottom = 0, numCharm = 0, numLight = 0;
      int numTags = 0;
      double sumVertexMass = 0.;
      // Loop over the jets and find out which are tagged
      const vector< pat::Jet >::const_iterator kJetEnd = jetCollection->end();
      for (vector< pat::Jet >::const_iterator jetIter = jetCollection->begin(); 
           kJetEnd != jetIter; 
           ++jetIter) 
      {
         // Is this jet tagged and does it have a good secondary vertex
         if( jetIter->bDiscriminator("simpleSecondaryVertexBJetTags") < 2.05 )
         {
            // This jet isn't tagged
            continue;
         }
         reco::SecondaryVertexTagInfo const * svTagInfos 
            = jetIter->tagInfoSecondaryVertex("secondaryVertex");
         if ( svTagInfos->nVertices() <= 0 ) 
         {
            // Given that we are using simple secondary vertex
            // tagging, I don't think this should ever happen.
            // Maybe we should put a counter here just to check.
            continue;
         } // if we have no secondary verticies
         
         // count it
         ++numTags;

         // What is the flavor of this jet
         int jetFlavor = std::abs( jetIter->partonFlavour() );
         if (5 == jetFlavor)
         {
            ++numBottom;
         } // if bottom 
         else if (4 == jetFlavor)
         {
            ++numCharm;
         } // if charm
         else
         {
            ++numLight;
         } // if light flavor

         // Calculate SecVtx Mass //
         ROOT::Math::LorentzVector< ROOT::Math::PxPyPzM4D<double> > sumVec;
         reco::CompositeCandidate vertexCand;
         reco::Vertex::trackRef_iterator 
            kEndTracks = svTagInfos->secondaryVertex(0).tracks_end();
         for (reco::Vertex::trackRef_iterator trackIter = 
                 svTagInfos->secondaryVertex(0).tracks_begin(); 
              trackIter != kEndTracks; 
              ++trackIter ) 
         {
            const double kPionMass = 0.13957018;
            ROOT::Math::LorentzVector< ROOT::Math::PxPyPzM4D<double> > vec;
            vec.SetPx( (*trackIter)->px() );
            vec.SetPy( (*trackIter)->py() );
            vec.SetPz( (*trackIter)->pz() );
            vec.SetM (kPionMass);
            sumVec += vec;
         } // for trackIter
         sumVertexMass += sumVec.M();
         if (2 == numTags)
         {
            // We've got enough.  Stop.
            break;
         } // if we have enough tags
      } // for jet

      // General Accounting //
      int numJets = std::min( (int) jetCollection->size(), 5 );
      eventCont.hist( sampleName + "_jettag")->Fill (numJets, numTags);

      // If we don't have any tags, don't bother going on
      if ( ! numTags)
      {
         continue;
      }

      // Calculate average SecVtx mass and //
      // fill appropriate histograms.      //
      sumVertexMass /= numTags;
      string whichtag = "";
      if (1 == numTags)
      {
         // single tag
         if      (numBottom)              whichtag = "_b";
         else if (numCharm)               whichtag = "_c";
         else if (numLight)               whichtag = "_q";
         else                             whichtag = "_X";
      } else {
         // double tags
         if      (2 == numBottom)         whichtag = "_bb";
         else if (2 == numCharm)          whichtag = "_cc";
         else if (2 == numLight)          whichtag = "_qq";
         else if (numBottom && numCharm)  whichtag = "_bc";
         else if (numBottom && numLight)  whichtag = "_bq";
         else if (numCharm  && numLight)  whichtag = "_bq";
         else                             whichtag = "_XX";
      } // if two tags
      string massName = sampleName 
         + Form("_secvtxMass_%dj_%dt", numJets, numTags);
      eventCont.hist(massName)->Fill (sumVertexMass);
      eventCont.hist(massName + whichtag)->Fill (sumVertexMass);
   } // for eventCont
      
   // ////////////////// //
   // // Clean Up Job // //
   // ////////////////// //

   // Histograms will be automatically written to the root file
   // specificed by command line options.

   // All done!  Bye bye.
   return 0;
}
void outputNameTagFunc ( string &  tag)

Definition at line 280 of file secvtxMassTemplates.cc.

{
   // If you do not want to give you output filename any "tag" based
   // on the command line options, simply do nothing here.  This
   // function is designed to be called by fwlite::EventContainer constructor.

   // if ( boolValue ("someCondition") )
   // { 
   //    tag += "_someCond";
   // }
}