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:
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:
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:
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
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:
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