-
Notifications
You must be signed in to change notification settings - Fork 2
05 Running an initial analysis
Prepare a CMSSW area, including a "SubSystem" (in our case we can just call it TestAnalyzer)
cmsrel CMSSW_12_2_1_patch1
cd CMSSW_12_2_1_patch1/src/
cmsenv
mkdir TestAnalyzer
cd TestAnalyzer/
Use mkedanlzr to create a skeleton analyzer.
mkedanlzr TrackPrinter
You will see the structure of the new directory. Go to the TrackAnalyzer/plugins subdirectory, and look at the structure of the TrackPrinter.cc file.
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/one/EDAnalyzer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/InputTag.h"
#include "DataFormats/TrackReco/interface/Track.h"
#include "DataFormats/TrackReco/interface/TrackFwd.h"
Basic infrastructure to setup an EDAnalyzer (Frameworkfwd.h, EDAnalyzer.h, MakerMacros.h),
access the current Event (Event.h),
access the CMSSW configuration file (ParameterSet.h)
and
get data from the event with a given "tag" (InputTag.h).
The example uses Tracks, so it automatically includes the Track.h and TrackFwd.h files.
Let's focus on some of the preamble. The line
class TrackPrinter : public edm::one::EDAnalyzer<edm::one::SharedResources> {
means that your analyzer (TrackPrinter) is a kind of EDAnalyzer (keyword: inheritance).
It has a couple of functions predefined.
Most important is the analyze() member function: this is the function that is automatically called by the framework for each event.
That means that the event loop (equivalent to a for (size_t i=0; i!=nEvents; ++i) {} loop) is automatically managed for you!
The function has access to a reference to both the current Event (const edm::Event&) and
to the current EventSetup (const edm::EventSetup&).
We will be using only the former for now.
Finally there is
edm::EDGetTokenT<TrackCollection> tracksToken_; //used to select what tracks to read from configuration file
that, as the comment says, holds a "token" that allows you to access a TrackCollection from the event.
TrackPrinter::TrackPrinter(const edm::ParameterSet& iConfig)
: tracksToken_(consumes<TrackCollection>(iConfig.getUntrackedParameter<edm::InputTag>("tracks"))) {
is the beginning of the the constructor.
Here you setup everything that you need to do at the beginning of your analysis.
In particular, we are warning the framework that we are going to "consume" a TrackCollection from the Event;
it needs to know that it order to set itself up to make things run as smooth as possible.
For instance, it may decide to find the TrackCollection for you in parallel as it is doing something else, since it is multithreaded.
We also let it know that the TrackCollection we are interested on has an InputTag that will be read from the configuration file, in the tracks parameter.
At this point the framework knows that, for every event, it has to make the "tracks" available for you in the tracksToken_ variable.
In the body of the analyze() function, we can tell the Event that we want our tracksToken_ ready, by using its get() function:
iEvent.get(tracksToken_)
In this example, we do everything in one go. We immediately use the return value of the get() function as a generator to loop over the tracks of the Event:
for (const auto& track : iEvent.get(tracksToken_)) {
// do something with track parameters, e.g, plot the charge.
// int charge = track.charge();
}
In principle, if you want to save the tracks you just go somewhere, you could just create a reference variable in the code and have them there for later.
const TrackCollection& theTracks = iEvent.get(tracksToken_);
for (const auto& track : theTracks) {
// do something with track parameters, e.g, plot the charge.
// int charge = track.charge();
}
By the way, how do you know what the Event get()s you? It depends on the token!
The tracksToken_ is of type edm::EDGetTokenT<TrackCollection>;
it is a token specialized in TrackCollection objects, much like a
std::vector<int> is a std::vector specialized in int objects (keyword: template).
So, the Event will give you back a TrackCollection.
By the way, a little secret: the TrackCollection is really just a nice name for a std::vector<reco::Track>
(keyword: typedef).
So, now that you can loop over the tracks, what can you do? In principle, we can already do analysis! The simplest thing is, of course, to print to the screen. Let's print their pt, but only for tracks with pt > 3 GeV:
const TrackCollection& theTracks = iEvent.get(tracksToken_);
for (const auto& track : theTracks) {
if(track.pt() > 3.0) {
std::cout << "This track pt is " << track.pt() << std::endl;
}
}
Compile your code with scram b. If it works you should see the line >> Package TestAnalyzer/TrackPrinter built in the output.
Now you need to, again, make a configuration file that has a Source, your module with a given label, and a Path that has your module in it. The testTrackPrinter_cfg.py has all that you need, we reproduce it here:
import FWCore.ParameterSet.Config as cms
# process
process = cms.Process("TEST")
# number of events to be processed and source file
process.maxEvents = cms.untracked.PSet(
input = cms.untracked.int32(400)
)
process.source = cms.Source("PoolSource",
fileNames = cms.untracked.vstring('/store/relval/CMSSW_12_2_0/RelValTTbar_14TeV/GEN-SIM-RECO/122X_mcRun3_2021_realistic_v5-v2/2580000/ac85ff65-dcea-4e7d-9995-d512f4bdafcf.root'
)
)
process.trkPrinter = cms.EDAnalyzer("TrackPrinter",
tracks = cms.untracked.InputTag("generalTracks")
)
process.p = cms.Path(process.trkPrinter)
Notice the name of your EDAnalyzer ("TrackPrinter") as opposed to its label in the code trkPrinter.
Notice also the name of the product you want to get from the Event ("generalTracks") as opposed to the parameter name that your name uses internally (tracks). Run it with
cmsRun testTrackPrinter_cfg.py
and you should have the pt ot the tracks in the screen!
...
Begin processing the 400th record. Run 1, Event 500, LumiSection 5 on stream 0 at 13-Apr-2022 23:19:01.000 CEST
This track pt is 5.45468
This track pt is 3.2081
This track pt is 17.7129
This track pt is 3.77042
...
cmsrel CMSSW_12_2_1_patch1
cd CMSSW_12_2_1_patch1/src/
cmsenv
mkdir TestAnalyzer
cd TestAnalyzer/
mkedanlzr TrackPrinter
cd TrackPrinter
# edit the plugins/TrackPrinter.cc file, or just get it from this repo:
wget https://raw.githubusercontent.com/SPRACE/sprace-cmssw-tutorial/main/TrackPrinter.cc -O plugins/TrackPrinter.cc
scram b
# get the config file from this repo:
wget https://raw.githubusercontent.com/SPRACE/sprace-cmssw-tutorial/main/testTrackPrinter_cfg.py -O test/testTrackPrinter_cfg.py
cmsRun test/testTrackPrinter_cfg.py