The information on this page is deprecated and not part of the WorkBook any more.

3.5.5 How to Make and Run FWLite Executables

Goals

This Twiki page will lead you through the steps necessary to copy, run, and understand two FWLite executable examples as well as modify one of them to create a third.

Setting up CMSSW Environment

This software is available for software releases after CMSSW_3_3_1.

Please visit here for help setting up CMSSW environment.

Build FWLite Executable - JetPt.exe

To create necessary source files and compile them into an executable:

cd $CMSSW_BASE/src
newFWLiteAna.py Analysis/SimpleExamples/myJetPt  --copy=jetPt --newPackage
scram b

In this case, newFWLiteAna.py:

  • Makes the necessary directory structure ( $CMSSW_BASE/src/AnalysisSimpleExamples/bin ). This mimics CMS's standard directory structure.
  • Makes (if necessary) and adds necessary lines to $CMSSW_BASE/src/AnalysisSimpleExamples/bin/CMS.BuildFile for a new FWLite executable (the CMS.BuildFile is CMS's equivalent to Makefile ).
  • Creates $CMSSW_BASE/src/AnalysisSimpleExamples/bin/myJetPt.cc (which is a copy of default jetPt.cc, the name in the heading )

scram b invokes CMS's build system and creates an executable myJetPt.exe . Note the executable created is myJetPt.exe and not JetPt.exe as the heading may suggest.

If this is the first time compiling and you are using tcsh shell this executable, you need to run the rehash command. You do not need to run this command if you are recompiling. If you don't know which shell you are using, you are probably using tcsh .

Also NOTE: --newPackage option is needed ONLY if it is the first time your are creating Directory/SubDirectory. In this case it means Analysis/SimpleExamples.

Now you are ready to use myJetPt.exe

Run JetPt.exe

myJetPt.exe inputFiles=/afs/cern.ch/cms/Tutorials/RelValTTbar_334.root \
     outputEvery=10 outputFile=myJetPt

Let us look at the command we just executed. In the above command we have the following:

  • The executable myJetPt.exe
  • The options inputFiles=... , outputEvery=... , outputFile=...

The option:

  • inputFiles=/afs/cern.ch/cms/Tutorials/RelValTTbar_334.root
    tells the executable what input file to use.
  • outputEvery=10
    tells the executable to print out lines like Processing Event: 1000 and gives you a measure of progress of running the code.
  • outputFile=myJetPt
    tells the executable the name of the output root file where your histograms are written. In this case it is myJetPt.root

For further information on command line options see Command_line_option_parsing

Here is the output you see on the screen as a result of executing the command above:

unix > myJetPt.exe inputFiles=/afs/cern.ch/cms/Tutorials/RelValTTbar_334.root \
     outputEvery=10 outputFile=myJetPt

------------------------------------------------------------------

Integer options:
    jobid          = -1             - jobID given by CRAB,etc. (-1 means append nothing)
    maxevents      = 0              - Maximum number of events to run over (0 for whole file)
    outputevery    = 10             - Output something once every N events (0 for never)
    section        = 0              - This section (from 1..totalSections inclusive)
    totalsections  = 0              - Total number of sections

Bool options:
    logname        = false          - Print log name and exit

String options:
    outputfile     =                - Output filename
        'myJetPt.root'
    storeprepend   =                - Prepend location on files starting with '/store/'
        ''
    tag            =                - A 'tag' to append to output file (e.g., 'v2', etc.)
        ''

String Vector options:
    inputfiles     =                - List of input files
        /afs/cern.ch/cms/Tutorials/RelValTTbar_334.root
        
    secondaryinputfiles =                - List of secondary input files (a.k.a. two-file-solution
        
------------------------------------------------------------------
Processing Event: 10
Processing Event: 20
Processing Event: 30
Processing Event: 40
Processing Event: 50
Processing Event: 60
Processing Event: 70
Processing Event: 80
Processing Event: 90
Processing Event: 100
EventContainer Summary: Processed 100 events.
TH1Store::write(): Successfully written to 'myJetPt.root'.


The first part of the printout is a listing of all the variables you can set from the command line and their values when the program is run. You can use --noPrint if you wish to turn this output off. See Command_line_option_parsing for more details

NOTE: The data file used here has 100 events only.

You should now see a root file called, in this case, myJetPt.root.

Before you open the root file, you may want to have rootlogon.C file setup, as described in section 3.5.1.3 in your current directory.

In order to open the root file do:

root -l myJetPt.root 
Then on the root prompt do
root [0] jetPt->Draw() 

If you choose log Y-scale you should see a plot like this:

jetPt

edm::Handle

Starting in CMSSW 3.3.1, one can now use edm::Handle s inside of FWLite. There are two advantages of this:

1. You can now use the same function calls in cmsRun and FWLite.

2. As a result of this, you can now share code libraries that work on events between cmsRun and FWLilte.

Details of the Code - JetPt.cc

You can browse the full code JetPt.cc here

The code has several parts:

CMS includes

// -*- C++ -*-

// CMS includes
#include "DataFormats/FWLite/interface/Handle.h"
#include "DataFormats/PatCandidates/interface/Jet.h"

#include "CMS.PhysicsTools/FWLite/interface/EventContainer.h"
#include "CMS.PhysicsTools/FWLite/interface/CommandLineParser.h" 

// Root includes
#include "TROOT.h"

using namespace std;

If you want to use other objects such as electron, photons etc, you would add some these includes files.

       #include "DataFormats/PatCandidates/interface/MET.h"
       #include "DataFormats/PatCandidates/interface/Photon.h"
       #include "DataFormats/PatCandidates/interface/Electron.h"
       #include "DataFormats/PatCandidates/interface/Tau.h"
       #include "DataFormats/TrackReco/interface/Track.h"

Main Subroutine

All executables in C++ need an int main() subroutine. This is what is run when the executable starts.

///////////////////////////
// ///////////////////// //
// // Main Subroutine // //
// ///////////////////// //
///////////////////////////

int main (int argc, char* argv[]) 
{

Command Line Options

Declare command line option parser. Give the parser a short summary of what this program does (will be visible when --help command is used).

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


       // Tell people what this analysis code does and setup default options.
       optutl::CommandLineParser parser ("Plots Jet Pt");

Change any defaults or add any new command line options

For example if you do not specify the option outputFile=myJetPt when running the myJetPt.exe, the default name jetPt.root specified in the code line below is used.

        ////////////////////////////////////////////////
        // Change any defaults or add any new command //
        //      line options you would like here.     //
        ////////////////////////////////////////////////
        parser.stringValue ("outputFile") = "jetPt.root";

After adding any new option or changing any defaults, tells the parser to parse the command line options.

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

For more details on command line parsing see Command_line_option_parsing

Create Event Container

We create an event container that initializes itself from the command line options parser (e.g., input files, output file, etc.).

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

       // This object 'eventCont' is used both to get all information from the
       // event as well as to store histograms, etc.
       fwlite::EventContainer eventCont (parser);

This object 'event' is used both to get all information from the event as well as to store histograms, etc.

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

Here is where you create ( "book") any histogram you want to fill later in the code.

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

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

        // Book those histograms!
        eventCont.add( new TH1F( "jetPt", "jetPt", 1000, 0, 1000) );

Event Loop

Loop over events in input files you specify at the command line. Also make a cast to the "edm::EventBase" to be able to access the same code in the same way in FWLite or the full framework.

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

        for (eventCont.toBegin(); ! eventCont.atEnd(); ++eventCont) 
        {

Extract Info From Event

Here the code:

  • Creates a "handle"
  • Tries to hook the handle upto a branch containing the selectedLayer1Jets
  • Makes sure that handle hook up is successful

Note: The following code is very similar to how you extract information from the event in cmsRun

           //////////////////////////////////
           // Take What We Need From Event //
           //////////////////////////////////
           edm::Handle< vector< pat::Jet > > jetHandle;
           eventCont.getByLabel (jetLabel, jetHandle);

A handle can be treated as pointer to whatever data format it is holding. For example, we can put const vector < pat::Jet > &jetvec = *handle and then use jetvec or we can use the handle directly as a pointer as the code does below:

   
         // Loop over the jets
         const vector< pat::Jet >::const_iterator kJetEnd = jetHandle->end();
         for (vector< pat::Jet >::const_iterator jetIter = jetHandle->begin();
              kJetEnd != jetIter; 
              ++jetIter) 
         {         

Fill pt() .

The following line of code does two distinct things:

  • get pt() for this jet
  • Fills histogram stored in the event container

            eventCont.hist("jetPt")->Fill (jetIter->pt());
         } // for jetIter
      } // for eventCont

Clean Up Job

Nothing much to do since histograms are automatically saved. Return 0 to indicate that this program was successful.

      ////////////////////////
      // ////////////////// //
      // // Clean Up Job // //
      // ////////////////// //
      ////////////////////////

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

     // All done!  Bye bye.
     return 0;
}

FWLite Executable Z peak Example

Build the executable. Here is a link to the zPeak.cc

newFWLiteAna.py Analysis/SimpleExamples/myZPeak --copy=zPeak
scram b
rehash
Also NOTE: Now you DO NOT need the option --newPackage as Analysis/SimpleExamples already exists.

Run the executable

myZPeak.exe inputFiles=/afs/cern.ch/cms/Tutorials/RelValZMM_334.root \
     outputEvery=10 outputFile=myZPeak 

You should now see root file called myZPeak.root If you open this root file you browse to the following plot:

zPeak

Let us look at the the code zPeak.cc to see how we looped over the muons. The snippet to loop over muons is here:

The following loop is effectively doing the

  • outer = [0, N-1]
    • inner = [outer+1, N]

This ensures that while combining two muons together, we do not try to combine a muon with itself, nor try any combination more than once.

 // O.k.  Let's loop through our muons and see what we can find.
      const vector< pat::Muon >::const_iterator kEndIter       = muonVec.end();
      const vector< pat::Muon >::const_iterator kAlmostEndIter = kEndIter - 1;
      for (vector< pat::Muon >::const_iterator outerIter = muonVec.begin();
           kAlmostEndIter != outerIter;
           ++outerIter)
      {
         for (vector< pat::Muon >::const_iterator innerIter = outerIter + 1;
              kEndIter != innerIter;
              ++innerIter)
         {

The following ensures that only pairs of muons with opposite charges will be used for as a Z candidate:

            // make sure that we have muons of opposite charge
            if (outerIter->charge() * innerIter->charge() >= 0) continue;

            // if we're here then we have one positively charged muon
            // and one negatively charged muon.

Here we get the 4-momentum of two muons, add them, get the invariant mass, and fill the histogram.

            eventCont.hist("Zmass")->Fill( (outerIter->p4() + innerIter->p4()).M() );
         } // for innerIter
      } // for outerIter

Modify Z peak

We are going to use myZpeak.cc to make a new code

cd $CMSSW_BASE/src
newFWLiteAna.py Analysis/SimpleExamples/myZPeakWithCuts  --copy=Analysis/SimpleExamples/bin/myZPeak.cc 

Edit myZPeakWithCuts.cc Change

parser.stringValue ("outputFile") = "zpeak1.root";

to

parser.stringValue ("outputFile") = "zpeak2.root";

and change

vector< pat::Muon > const & muonVec = *muonHandle;

to

      // Create a new vector only with muons that pass our cuts
      vector< pat::Muon > muonVec;
      for (vector< pat::Muon >::const_iterator iter = muonHandle->begin();
           muonHandle->end() != iter;
           ++iter)
      {
         if (iter->pt() > 20 && std::abs(iter->eta()) < 2.5)
         {
            muonVec.push_back( *iter );
         }
      }

Then do:

scram b

Remember to run rehash the first time you successfully compile.

Run the code:

myZPeakWithCuts.exe inputFiles=/afs/cern.ch/cms/Tutorials/RelValZMM_334.root \
     outputEvery=10 outputFile=myZPeakModified

You should now see root file called myZPeakModified.root

Using the ROOT commands below, you can super impose the modified ZPeak and the ZPeak we had made before.

root -l 
root [0] TFile::Open("myZPeak.root")
(class TFile*)0x8366578
root [1] Zmass->Draw()
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [2] TFile::Open("myZPeakModified.root")
(class TFile*)0x85776a0
root [3] Zmass->SetLineColor(kRed)
root [4] Zmass->Draw("Same")
root [5] 

The superimposed plots are:

zPeak_zPeakModified

References

Command line option parsing

Command line option parsing is a method of letting you set the values of different variables when running your FWLite executable from the command line. By default several options are hooked up for you (e.g., inputFiles is the list (std::vector) of files to run over, outputFile is the name of the root file where your histograms will be stored).

You will be able to add new command line options, change the default values of the default command line options, as well as learn how to easily set these options from the command line.

Defining Variables

To define options, one gives:

  • A name,
  • A type,
    • kInteger,
    • kDouble,
    • kString,
    • kBool,
    • kIntegerVector,
    • kDoubleVector, or
    • kStringVector.
  • A description, and
  • (If desired for a non-vector type,) a default value. If this is not given for a non-vector type, 0/""/false is chosen.

For example, here are two variables I hooked up in btagTemplates.cc above:

   parser.addOption ("mode",         optutl::CommandLineParser::kInteger, 
                      "Normal(0), VQQ(1), LF(2), Wc(3)", 
                      0);   
   parser.addOption ("sampleName",   optutl::CommandLineParser::kString, 
                      "Sample name (e.g., top, Wqq, etc.)");   

Here are the default six options that are automatically hocked up:

   parser.addOption ("inputFiles",    kStringVector,
                      "List of input files");
   parser.addOption ("totalSections", kInteger,
                      "Total number of sections",
                       0);
   parser.addOption ("section",       kInteger,
                      "This section (from 1..totalSections inclusive)",
                      0);
   parser.addOption ("maxEvents",     kInteger,
                      "Maximum number of events to run over (0 for whole file)",
                      0);
   parser.addOption ("outputFile",    kString,
                      "Output filename",
                      "output.root");
   parser.addOption ("outputEvery",   kInteger,
                      "Output something once every N events (0 for never)",
                     100);

Accessing Options

To access these variables, you use one of the following access functions:
   int         &integerValue  (std::string key);
   double      &doubleValue   (std::string key);
   std::string &stringValue   (std::string key);
   bool        &boolValue     (std::string key);
   IVec        &integerVector (std::string key);
   DVec        &doubleVector  (std::string key);
   SVec        &stringVector  (std::string key);

Note that these are references and not const references, so you can use these functions to set variables as well. For example, if you wanted to change the default of maxEvents to 10, you can put:
   optutl::integerValue ("maxEvents") = 10;
before the optutl::parseArguments() function call.

Setting Command Line Options

The general way to set a command line option is -varName=value. Here are the rules:

  • General Idea : -varName=value
  • kBool values should be set with 1 for true, 0.
  • Vector values can be set in any mixture of multiple times (e.g., inputFiles=one.root inputFiles=two.root) or with a comma separated list (e.g., inputFiles=three.root,four.root).
  • Vector values can be loaded from a text file (e.g.,=inputFiles_load=fileListingRootFiles.txt=).
  • If you have defined default values for a vector in the code, you can clear the default from the command line (e.g., inputFiles_clear=true).
  • --help will print out all values, their descriptions, and their default values as well as the usage string (set by optutl::setUsageString()) and then exit.
  • By default, all variables, their descriptions, and their current values will be printed and then continue running. However, using the --noPrint option will suppress these print messages.

Try the options, example

Type
newJetPt.exe --help 
in Analysis/SimpleExamples/newJetPt/bin= directory. You see all the options available as below:

jetPt.exe - Plots Jet Pt
------------------------------------------------------------------

Integer options:
    jobid          = -1             - jobID given by CRAB,etc. (-1 means append nothing)
    maxevents      = 0              - Maximum number of events to run over (0 for whole file)
    outputevery    = 0              - Output something once every N events (0 for never)
    section        = 0              - This section (from 1..totalSections inclusive)
    totalsections  = 0              - Total number of sections

Bool options:
    logname        = false          - Print log name and exit

String options:
    outputfile     =                - Output filename
        'output.root'
    storeprepend   =                - Prepend location on files starting with '/store/'
        ''
    tag            =                - A 'tag' to append to output file (e.g., 'v2', etc.)
        ''

String Vector options:
    inputfiles     =                - List of input files
        
------------------------------------------------------------------

In the options, the most important ones are inputfiles and the outputfiles. Option logname can be used to have in Crab jobs to have the sane name for the log file and output file. Options section and totalsections are used to split the number of input file data files. For example your relval_ttbar_300pre8.filelist [ Get the data files first] below has 50 files. You can split input of these 50 files,say, by putting section equal to 5 and totalsection equal to 10.

Histogram storage:

fwlite::EventContainer not only contains what is necessary to access data in the event, but also what is needed for users to store histograms. These histograms will be automatically saved at the end of the job in the file specified by outputName command line option.

1. eventCont.add() is used to store a newly created histogram:

 eventCont.add( new TH1F("ZMass", "Mass of Z candidate", 100, 50, 150) );
 

If you want to store histograms in a directory, simply add the name of the directory after the histogram pointer:

 eventCont.add( new TH1F("ZMass", "Mass of Z candidate", 100, 50, 150),
                "parentDir/subDir");
 

In both cases, the histogram will be accessed using the name "ZMass" (see below).

2. eventCont.hist() is used to access the histograms:

 eventCont.hist ("myHistogram")->Fill (myVariable);

Backporting to 3.1.x or 3.2.x

If you are using CMSSW_3_1_X or CMSSW_3_2_X, you need to checkout and build the following tags:

Package Tag
CMS.PhysicsTools/FWLite V02-00-06
DataFormats/FWLite V00-13-00

Responsible: CharlesPlager and SudhirMalik
Last reviewed by: SudhirMalik - 4 Feb 2010

Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng jetPt.png r4 r3 r2 r1 manage 16.3 K 2010-02-04 - 05:14 SudhirMalik  
C source code filec rootlogon.C r1 manage 0.1 K 2009-07-31 - 14:45 SudhirMalik  
PNGpng sudhir_maxevt100root.png r1 manage 18.7 K 2009-07-24 - 00:25 SudhirMalik  
PNGpng sudhir_maxevt100rootBrowser.png r1 manage 20.9 K 2009-07-30 - 21:36 SudhirMalik  
PNGpng sudhir_maxevt100rootBrowser2.png r1 manage 18.1 K 2009-07-30 - 21:52 SudhirMalik  
PNGpng zPeak.png r4 r3 r2 r1 manage 18.0 K 2010-02-04 - 07:39 SudhirMalik  
PNGpng zPeakModified.png r4 r3 r2 r1 manage 17.4 K 2010-02-04 - 08:00 SudhirMalik  
PNGpng zPeak_zPeakModified.png r4 r3 r2 r1 manage 18.1 K 2010-02-04 - 07:55 SudhirMalik  
Edit | Attach | Watch | Print version | History: r25 < r24 < r23 < r22 < r21 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r25 - 2011-01-21 - PeterJones


ESSENTIALS

ADVANCED TOPICS


 
    • 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-2023 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