Tools for inclusive muon plots
Within the
MuonAnalysis/Examples
package, there's a set of tools that can be used to produce comparison plots for muon variables.
Overview
The tools consist of:
- InclusiveMuonPlots
: a CMSSW analyzer module that runs on a collection of muons (reco or pat ones), applies a configurable selection cut and then plots a set of standard variables for those muons (with a configurable choice of binning)
- inclusiveMuonPlots_step2.py
: a pyroot macro that can manipulate the rootfiles with the histograms produced by the above analyzer: it takes care of normalizing and stacking plots (e.g. for data vs mc), labelling and pretty-printing, and produces a summary html page with all the plots
The separation of the MC into different categories according to the origin of muons is done by another package in
MuonAnalysis/MuonAssociators
Recipes
The production of DATA/MC plots is normally performed in stages:
- Run on your input events, produce a PAT-tuple with only the interesting information
- Run on the PAT-tuple, produce histograms and merge the output of multiple jobs with
hadd
- Stack histograms together to produce the final plots
You can combine the first two steps, but then you'll have to go back to the original sample every time you want to add a new variable or new muon selection, change the binning, ...
The following recipe works from
CMSSW_3_8_0_patch2 (or newer), running samples reconstructed with at least
CMSSW_3_6_X. If you really need older releases, you can find info below.
Check out the following packages:
MuonAnalysis/MuonAssociators V01-10-02
MuonAnalysis/Examples V00-04-01
Production of the PAT-tuples
You might want to review:
- the global tag
- the skim criteria (e.g. the trigger paths to use)
- the definition of good collision event
- the trigger process name: most of the 2010 MC production has a non-standard trigger name
- the event content, to save some disk space if you don't need trigger information
Filling histograms
There are two pairs of cfg files provided under
MuonAnalysis/Examples/test/inclusiveMuonPlots
You can make simple changes to the first cfg file:
- change the muon selection; if you switch to different categories of muons, you have also to change the label for the classification by hits to
classByHitsTM
(all tracker muons), classByHitsTMLSAT
(tracker muons last station ang tight), classByHitsGlb
(global muons) and classByHitsSta
(standalone muons)
- change the trigger
Stacking plots
For the more basic case, just do
python inclusiveMuonPlots_step2.py data.root globalMuons -r mc.root -n integral -c "Punch(1),Ghost(8),Light(207),Heavy(67)" -O -R --RR --legend=legend.txt -o plots
This will:
- take the data from
data.root
and the mc from mc.root
- use the muon selection of the module
globalMuons
- normalize the histograms to the same area (read below for other options)
- save the output in the
plots
folder
- decompose MC in four categories, using the specified root color numbers
- add a legend from
legend.txt
, add the overflow bin (-O-
), add raito plots (-R
) with automatic re-binning (--RR
)
To make the full suite of plots for the ICHEP analysis, you can use the already provided script
makePlots.sh
Working with older releases and samples
If you have to run on
MC samples reconstructed with CMSSW_3_5_X follow this additional recipe before producing the PAT-tuples
addpkg SimMuon/MCTruth
cd SimMuon/MCTruth
cvs update -rV02-05-00-03 src/TrackerMuonHitExtractor.cc
scramv1 b -j 4
This is not needed for real data.

The following two other recipes are not really supported, although they might work
If you're running from a release between
CMSSW_3_6_1_patch4
and
CMSSW_3_7_X
, you also need
SimTracker/TrackAssociation V01-08-17
SimMuon/MCTruth V02-06-03 (or V02-05-00-03 for 3.5.X samples)
The production of plots can't be done in
CMSSW_3_5_X
. However, you can still make the PAT-tuples from
CMSSW_3_5_8
and then use a newer release to make the plots.
In this case, check out
SimGeneral/TrackingAnalysis V04-01-05
SimTracker/TrackAssociation V01-08-17
MuonAnalysis/Examples V00-03-03
MuonAnalysis/MuonAssociators V01-09-01
SimMuon/MCTruth V02-06-03 (or V02-05-00-03 for 3.5.X samples)
Detailed documentation
InclusiveMuonPlots module
The InclusiveMuonPlots module fills histograms from a collection of muons after applying a quality cut.
Configuration
Module configuration: the module requires three basic parameters:
-
muons
: a cms.InputTag
to a collection of reco::Muon
or pat::Muon
objects (or references to them)
-
selection
: a cms.string
with a quality cut to be applied at the muons before making the plots. All the datamembers and methods of the pat::Muon
object can be used for the selection, with the usual syntax of the CMS.PhysicsTools cut parser; in particular, the muon ID selections can be applied as muonID('name')
-
primaryVertices
: cms.InputTag
to the collection of primary vertices, to compute the impact parameter.
Then, for each plot or set of plots, the module reads as input the binning to use: e.g. for the plot of
pt
, it will read the parameter
ptBins
(which should be a
cms.vdouble
containing all the bin boundaries)
There is a configuration file for the module under
python/inclusiveMuonPlots_cfi.py
. For some variables that don't have a natural choice of binning, you might want to rebin according to the statistics you have, following this snippet
from MuonAnalysis.Examples.inclusiveMuonPlots_cfi import *
process.inclusiveMuonPlots = cms.EDAnalyzer("InclusiveMuonPlots",
makeInclusiveMuonPlots(1), # change "1" to your rebin factor; it can be a fractionary number, like 0.5
muons = cms.InputTag('muons'),
selection = cms.string("isGlobalMuon && muonID('GlobalMuonPromptTight')"), # or anything else
primaryVertices = cms.InputTag("offlinePrimaryVertices"),
)
Code
A brief overview of the code:
- In the constructor, the module bins the plots. This is done using the function
book
, which reads the binning from the ParameterSet and books the TH1D using the TFileService putting it into a std::map<std::string, TH1*>
from which it can be retrieved later.
- In the
analyze
module the code retrieves the muons, if necessary converts them on the fly into pat::Muons, applies the selection cut and then proceeds filling the plots
- There is some code in the endLuminosityBlock that was used to normalize the plots by reading the numer of good collision events; now that luminosity measurement is working, this is no longer used.
PyROOT script to print and stack the plots
The script
inclusiveMuonPlots_step2.py
reads one or two sets of histograms and produces plots a set of plots and an html page. Its behaviour is controlled by a set of command-line options, of which you can get a listing by invoking it with the
--help
argument.
Plotting a single dataset: to print the plots inside the directory
dir
of a rootfile
file.root
, do
inclusiveMuonPlots_step2.py file.root dir
The relevant command-line options are
- You can define the output directory where to put the plots using option
--out
(or just -o
)
- You can include the *overflow3 and underflow bins using option
--overflow
(or just -O
)
- You can specify the text file containing the labels and titles of the plots with option
--titles
(or just -t
); by default, it reads from inclusiveMuonPlots_titles.txt
- You can print only a selected set of plots using option
--select
(or -s
) giving as argument a regular expression
to match against the plot names
- To add a statistics box to the plots, use option
--stat
(or -S
). It's likely to look awful, you have been warned.
Comparing datasets: to compare plots in
file.root
with those in
ref.root
, do
inclusiveMuonPlots_step2.py file.root dir -r ref.root
The relevant command-line options are
- The reference file is specified through option
--reference-file
(or just -r
)
- If you want to compare with plots from a different directory, use option
--reference-dir
(or --rd
).
- To add for each histogram a plot of the ratio between the two distributions, use option
--ratio
(or -R
)
The
normalization is specified using the parameter
--normalize
(or
-n
), which can take the following values:
-
none
: no normalization is performed; good e.g. to compare a sample with it's re-processed version to spot differences
-
integral
: each plot is normalized according to the number of entries
-
manual,<X>
: reference plots are scaled by a factor X (any valid floating point number, e.g. 37 or 0.012; it's up to you to compute it, e.g. from luminosity). Note that there is no space between the comma and the number.
-
external
(obsolete): reference plots are scaled according to the normalization computed from the count of events in the processed lumi-sections and stored in the normalization
histogram within the file
Using stacked histograms instead of a single reference histogram
The latest versions of the script can use as reference a stack of histograms instead of a single histogram if the
composite
option is specified. In order to do this, you need to run N+1 copies of the analyzer in the job that creates plots, one instance making the overall histogram and N instances each making a component of the stack. The procedure is better described with an example:
- Let
ref
be the label of the analyzer that makes the overall histograms, and refAbc
, refXyz
and refPqr
be the three instances that make the separate components of the stack (they must be the overall label followed by a name beginning with an uppercase letter)
- Choose the ROOT color codes
for each component (e.g. 7, 42, 99
)
- The syntax of the option will be
--rd ref --composite="Abc(7),Xyz(42),Pqr(99)"
(the ordering is bottom to top: "Abc" will be the lowest one, "Pqr" the top one)
As for normal comparisons, you can omit the option specyfing the reference directory if it's the same as the dirrectory used for the main plot (i.e."data").
When using composite mode, the statistical uncertainty on the reference sample is shown as a gray crosshatched rectangle on top of the stacked plot.
Using the muon classification by hits in the plots
The main application of the stacked plots option described above is to make reference plots from MC using the
muon classification by hits.
The procedure to follow in this case is:
- Run the module for the classification by hits described in the above link, and store the information into
pat::Muons
(as described in part 2B of the example in that twiki)
- For a given muon selection
myMuons
, define four clones with extra selection cuts
-
myMuonsGhost
with extra cut -5 <= userInt('%s') <= -1
(replace the %s
with classByHitsGlb
for global muons, classByHitsTM
for tracker muons, classByHitsTMLSAT
for TMLastStationAngTight
, ...)
-
myMuonsPunch
with extra cut 0 <= userInt('%s')) <= 1
-
myMuonsLight
with extra cut userInt('%s') == 3
-
myMuonsHeavy
with extra cut userInt('%s') == 4
- If you have primary muons from W/Z/γ e.g. because you're running on TTbar mc, add also
myMuonsPrimary
with extra cut userInt('%s') == 5
- Run also all the clones of the modules
- Use this as argument of the
composite
option: Punch(1),Ghost(8),Light(207),Heavy(67)
(possibly adding also Primary if you want it )
Adding plots to the suite
If you want to add some plots into the module, proceed as follows:
1) In the constructor, book the plots specifying a name; you can book multiple plots with the same binning.
// books a plot called <plotname>, with binning <plotname>Bins in the cfg file
book(*fs, pset, "<plotname>");
// books two plots using the same binning
// specified as <template>Bins in the cfg file
book(*fs, pset, "<plot1>", "<template>");
book(*fs, pset, "<plot2>", "<template>");
2) In the
analyze
method, fill the plot. If your variable can be computed only under some circumstances (e.g. muons with a standalone track) or requires something besides the track (e.g. the TrackExtra to use the
outerPosition()
method), please the code by checking
isNonnull()
and
isAvailable()
so that the module is still usable on all muons.
if (mu.globalTrack().isNonnull() && mu.globalTrack()->extra().isAvailable()) {
plots["glbOuterRho"]->Fill(mu.globalTrack()->outerPosition().Rho());
}
3) Add the parameter in the cfi file
python/inclusiveMuonPlots_cfi.py
, in the
makeInclusiveMuonPlots
function:
- for even binning of a given size, times rebin factor, you can use
plotName = _evenBins(low, high, binsize * rebinFactor)
- for fixed binning you can use
plotName = _nBins(n, low, high)
- for some ad-hoc binning, just define
plotName = cms.vdouble(... all bin edges ...)
4) Add the pretty title and x-axis label for the plot in
test/inclusiveMuonPlots_titles.txt
(it's not required, but it's nice to have).
The syntax is simply
plotName: x-label: title
; you can use ROOT's syntax for subscripts, superscripts and symbols.
5) Write to
RiccardoBellan to get cvs access to the
MuonAnalysis/Examples
package so that you can commit the code and eveybody can benefit from your work.