CMS 3D CMS Logo

ElectronMVANtuplizer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: RecoEgamma/ElectronIdentification
4 // Class: ElectronMVANtuplizer
5 //
13 //
14 // Original Author: Jonas REMBSER
15 // Created: Thu, 22 Mar 2018 14:54:24 GMT
16 //
17 //
18 
19 
20 // user include files
37 
38 #include <TTree.h>
39 #include <TFile.h>
40 #include <Math/VectorUtil.h>
41 
42 //
43 // class declaration
44 //
45 
46 class ElectronMVANtuplizer : public edm::one::EDAnalyzer<edm::one::SharedResources> {
47  public:
48  explicit ElectronMVANtuplizer(const edm::ParameterSet&);
49 
50  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
51 
52  private:
53  void analyze(const edm::Event&, const edm::EventSetup&) override;
54 
55  // method called once each job just before starting event loop
56  void beginJob() override {};
57  // method called once each job just after ending the event loop
58  void endJob() override {};
59 
62 
63  // ----------member data ---------------------------
64 
65  //global variables
66  int nEvent_;
67  int nRun_;
68  int nLumi_;
69  int genNpu_;
70  int vtxN_;
71 
72  // electron variables
73  float eleQ_;
74  int ele3Q_;
76 
77  std::vector<float> energyMatrix_;
78 
79  // gap variables
80  bool eleIsEB_;
81  bool eleIsEE_;
87 
88  int eleIndex_;
89 
90  // config
91  const bool isMC_;
92  const double deltaR_;
93  const double ptThreshold_;
94 
95  // ID decisions objects
96  const std::vector< std::string > eleMapTags_;
97  std::vector< edm::EDGetTokenT< edm::ValueMap<bool> > > eleMapTokens_;
98  const std::vector< std::string > eleMapBranchNames_;
99  const size_t nEleMaps_;
100 
101  // MVA values and categories (optional)
102  const std::vector< std::string > valMapTags_;
103  std::vector< edm::EDGetTokenT<edm::ValueMap<float> > > valMapTokens_;
104  const std::vector< std::string > valMapBranchNames_;
105  const size_t nValMaps_;
106 
107  const std::vector< std::string > mvaCatTags_;
108  std::vector< edm::EDGetTokenT<edm::ValueMap<int> > > mvaCatTokens_;
109  const std::vector< std::string > mvaCatBranchNames_;
110  const size_t nCats_;
111 
112  // Tokens for AOD and MiniAOD case
119 
120  // to hold ID decisions and categories
121  std::vector<int> mvaPasses_;
122  std::vector<float> mvaValues_;
123  std::vector<int> mvaCats_;
124 
125  // To get the auxiliary MVA variables
127 
128  // other
129  TTree* tree_;
130 
132  const int nVars_;
133  std::vector<float> vars_;
134 
135  const bool doEnergyMatrix_;
136  const int energyMatrixSize_;
137 };
138 
139 //
140 // constants, enums and typedefs
141 //
142 
148  }; // The last does not include tau parents
149 
150 //
151 // constructors and destructor
152 //
154  : isMC_ (iConfig.getParameter<bool>("isMC"))
155  , deltaR_ (iConfig.getParameter<double>("deltaR"))
156  , ptThreshold_ (iConfig.getParameter<double>("ptThreshold"))
157  , eleMapTags_ (iConfig.getParameter<std::vector<std::string>>("eleMVAs"))
158  , eleMapBranchNames_ (iConfig.getParameter<std::vector<std::string>>("eleMVALabels"))
160  , valMapTags_ (iConfig.getParameter<std::vector<std::string>>("eleMVAValMaps"))
161  , valMapBranchNames_ (iConfig.getParameter<std::vector<std::string>>("eleMVAValMapLabels"))
163  , mvaCatTags_ (iConfig.getParameter<std::vector<std::string>>("eleMVACats"))
164  , mvaCatBranchNames_ (iConfig.getParameter<std::vector<std::string>>("eleMVACatLabels"))
166  , src_ (consumesCollector(), iConfig, "src" , "srcMiniAOD")
167  , vertices_ (src_, consumesCollector(), iConfig, "vertices" , "verticesMiniAOD")
168  , pileup_ (src_, consumesCollector(), iConfig, "pileup" , "pileupMiniAOD")
169  , genParticles_ (src_, consumesCollector(), iConfig, "genParticles", "genParticlesMiniAOD")
170  , ebRecHits_ (src_, consumesCollector(), iConfig, "ebReducedRecHitCollection", "ebReducedRecHitCollectionMiniAOD")
171  , eeRecHits_ (src_, consumesCollector(), iConfig, "eeReducedRecHitCollection", "eeReducedRecHitCollectionMiniAOD")
174  , mvaCats_ (nCats_)
176  , mvaVarMngr_ (iConfig.getParameter<std::string>("variableDefinition"))
177  , nVars_ (mvaVarMngr_.getNVars())
178  , vars_ (nVars_)
179  , doEnergyMatrix_ (iConfig.getParameter<bool>("doEnergyMatrix"))
180  , energyMatrixSize_ (iConfig.getParameter<int>("energyMatrixSize"))
181 {
182  // eleMaps
183  for (auto const& tag : eleMapTags_) {
185  }
186  // valMaps
187  for (auto const& tag : valMapTags_) {
189  }
190  // categories
191  for (auto const& tag : mvaCatTags_) {
193  }
194 
195  // Book tree
196  usesResource(TFileService::kSharedResource);
198  tree_ = fs->make<TTree>("tree","tree");
199 
200  tree_->Branch("nEvent", &nEvent_);
201  tree_->Branch("nRun", &nRun_);
202  tree_->Branch("nLumi", &nLumi_);
203  if (isMC_) tree_->Branch("genNpu", &genNpu_);
204  tree_->Branch("vtxN", &vtxN_);
205 
206  tree_->Branch("ele_q",&eleQ_);
207  tree_->Branch("ele_3q",&ele3Q_);
208 
209  if (doEnergyMatrix_) tree_->Branch("energyMatrix",&energyMatrix_);
210 
211  if (isMC_) tree_->Branch("matchedToGenEle", &matchedToGenEle_);
212 
213  for (int i = 0; i < nVars_; ++i) tree_->Branch(mvaVarMngr_.getName(i).c_str(), &vars_[i]);
214 
215  tree_->Branch("ele_isEB",&eleIsEB_);
216  tree_->Branch("ele_isEE",&eleIsEE_);
217  tree_->Branch("ele_isEBEtaGap",&eleIsEBEtaGap_);
218  tree_->Branch("ele_isEBPhiGap",&eleIsEBPhiGap_);
219  tree_->Branch("ele_isEBEEGap", &eleIsEBEEGap_);
220  tree_->Branch("ele_isEEDeeGap",&eleIsEEDeeGap_);
221  tree_->Branch("ele_isEERingGap",&eleIsEERingGap_);
222 
223  tree_->Branch("ele_index",&eleIndex_);
224 
225  // IDs
226  for (size_t k = 0; k < nValMaps_; ++k) {
227  tree_->Branch(valMapBranchNames_[k].c_str() , &mvaValues_[k]);
228  }
229 
230  for (size_t k = 0; k < nEleMaps_; ++k) {
231  tree_->Branch(eleMapBranchNames_[k].c_str() , &mvaPasses_[k]);
232  }
233 
234  for (size_t k = 0; k < nCats_; ++k) {
235  tree_->Branch(mvaCatBranchNames_[k].c_str() , &mvaCats_[k]);
236  }
237 }
238 
239 
240 // ------------ method called for each event ------------
241 void
243 {
244  // Fill global event info
245  nEvent_ = iEvent.id().event();
246  nRun_ = iEvent.id().run();
247  nLumi_ = iEvent.luminosityBlock();
248 
249  // Get Handles
250  auto src = src_.getValidHandle(iEvent);
251  auto vertices = vertices_.getValidHandle(iEvent);
252 
253  // initialize cluster tools
254  std::unique_ptr<noZS::EcalClusterLazyTools> lazyTools;
255  if(doEnergyMatrix_) {
256  // Configure Lazy Tools, which will compute 5x5 quantities
257  lazyTools = std::make_unique<noZS::EcalClusterLazyTools>(
258  iEvent, iSetup, ebRecHits_.get(iEvent), eeRecHits_.get(iEvent));
259  }
260 
261  // Get MC only Handles, which are allowed to be non-valid
262  auto genParticles = genParticles_.getHandle(iEvent);
263  auto pileup = pileup_.getHandle(iEvent);
264 
265  vtxN_ = vertices->size();
266 
267  // Fill with true number of pileup
268  if(isMC_) {
269  for(const auto& pu : *pileup)
270  {
271  int bx = pu.getBunchCrossing();
272  if(bx == 0)
273  {
274  genNpu_ = pu.getPU_NumInteractions();
275  break;
276  }
277  }
278  }
279 
280  // Get MVA decisions
282  for (size_t k = 0; k < nEleMaps_; ++k) {
283  iEvent.getByToken(eleMapTokens_[k],decisions[k]);
284  }
285 
286  // Get MVA values
288  for (size_t k = 0; k < nValMaps_; ++k) {
289  iEvent.getByToken(valMapTokens_[k],values[k]);
290  }
291 
292  // Get MVA categories
294  for (size_t k = 0; k < nCats_; ++k) {
295  iEvent.getByToken(mvaCatTokens_[k],mvaCats[k]);
296  }
297 
298  eleIndex_ = src->size();
299  for(auto const& ele : src->ptrs())
300  {
301  if (ele->pt() < ptThreshold_) continue;
302 
303  // Fill the energy matrix around the seed
304  if(doEnergyMatrix_) {
305  const auto& seed = *(ele->superCluster()->seed());
306  energyMatrix_ = lazyTools->energyMatrix(seed, energyMatrixSize_);
307  }
308 
309  // Fill various tree variable
310  eleQ_ = ele->charge();
311  ele3Q_ = ele->chargeInfo().isGsfCtfScPixConsistent;
312 
313  for (int iVar = 0; iVar < nVars_; ++iVar) {
314  std::vector<float> extraVariables = variableHelper_.getAuxVariables(ele, iEvent);
315  vars_[iVar] = mvaVarMngr_.getValue(iVar, *ele, extraVariables);
316  }
317 
318  if (isMC_) {
319  matchedToGenEle_ = matchToTruth( *ele, *genParticles);
320  }
321 
322  // gap variables
323  eleIsEB_ = ele->isEB();
324  eleIsEE_ = ele->isEE();
325  eleIsEBEEGap_ = ele->isEBEEGap();
326  eleIsEBEtaGap_ = ele->isEBEtaGap();
327  eleIsEBPhiGap_ = ele->isEBPhiGap();
328  eleIsEEDeeGap_ = ele->isEEDeeGap();
329  eleIsEERingGap_ = ele->isEERingGap();
330 
331  //
332  // Look up and save the ID decisions
333  //
334  for (size_t k = 0; k < nEleMaps_; ++k) mvaPasses_[k] = static_cast<int>((*decisions[k])[ele]);
335  for (size_t k = 0; k < nValMaps_; ++k) mvaValues_[k] = (*values[k])[ele];
336  for (size_t k = 0; k < nCats_ ; ++k) mvaCats_[k] = (*mvaCats[k])[ele];
337 
338  tree_->Fill();
339  }
340 
341 }
342 
345 {
346  //
347  // Explicit loop and geometric matching method (advised by Josh Bendavid)
348  //
349 
350  // Find the closest status 1 gen electron to the reco electron
351  double dR = 999;
352  reco::GenParticle const* closestElectron = nullptr;
353  for(auto const& particle : genParticles) {
354  // Drop everything that is not electron or not status 1
355  if( std::abs(particle.pdgId()) != 11 || particle.status() != 1 )
356  continue;
357  //
358  double dRtmp = ROOT::Math::VectorUtil::DeltaR( electron.p4(), particle.p4() );
359  if( dRtmp < dR ){
360  dR = dRtmp;
361  closestElectron = &particle;
362  }
363  }
364  // See if the closest electron is close enough. If not, no match found.
365  if( closestElectron == nullptr || dR >= deltaR_ ) return UNMATCHED;
366 
367  if( closestElectron->fromHardProcessFinalState() ) return TRUE_PROMPT_ELECTRON;
368 
370 
371  // What remains is true non-prompt electrons
373 }
374 
375 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
376 void
378 {
380  desc.add<edm::InputTag>("src", edm::InputTag("gedGsfElectrons"));
381  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
382  desc.add<edm::InputTag>("pileup", edm::InputTag("addPileupInfo"));
383  desc.add<edm::InputTag>("genParticles", edm::InputTag("genParticles"));
384  desc.add<edm::InputTag>("srcMiniAOD", edm::InputTag("slimmedElectrons"));
385  desc.add<edm::InputTag>("verticesMiniAOD", edm::InputTag("offlineSlimmedPrimaryVertices"));
386  desc.add<edm::InputTag>("pileupMiniAOD", edm::InputTag("slimmedAddPileupInfo"));
387  desc.add<edm::InputTag>("genParticlesMiniAOD", edm::InputTag("prunedGenParticles"));
388  desc.add<edm::InputTag>("ebReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsEB"));
389  desc.add<edm::InputTag>("eeReducedRecHitCollection", edm::InputTag("reducedEcalRecHitsEE"));
390  desc.add<edm::InputTag>("ebReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedEBRecHits"));
391  desc.add<edm::InputTag>("eeReducedRecHitCollectionMiniAOD", edm::InputTag("reducedEgamma","reducedEERecHits"));
392  desc.add<std::string>("variableDefinition");
393  desc.add<bool>("doEnergyMatrix", false);
394  desc.add<int>("energyMatrixSize", 2)->setComment("extension of crystals in each direction away from the seed");
395  desc.add<bool>("isMC", true);
396  desc.add<double>("deltaR", 0.1);
397  desc.add<double>("ptThreshold", 5.0);
398  desc.add<std::vector<std::string>>("eleMVAs", {});
399  desc.add<std::vector<std::string>>("eleMVALabels", {});
400  desc.add<std::vector<std::string>>("eleMVAValMaps", {});
401  desc.add<std::vector<std::string>>("eleMVAValMapLabels", {});
402  desc.add<std::vector<std::string>>("eleMVACats", {});
403  desc.add<std::vector<std::string>>("eleMVACatLabels", {});
404  descriptions.addDefault(desc);
405 
406 }
407 
408 //define this as a plug-in
RunNumber_t run() const
Definition: EventID.h:39
size
Write out results.
static const std::string kSharedResource
Definition: TFileService.h:76
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
EventNumber_t event() const
Definition: EventID.h:41
const std::string & getName(int index) const
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:228
const MVAVariableHelper< reco::GsfElectron > variableHelper_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
bool isDirectHardProcessTauDecayProductFinalState() const
Definition: GenParticle.h:84
const MultiTokenT< edm::View< reco::GenParticle > > genParticles_
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:61
T * make(const Args &...args) const
make new ROOT object
Definition: TFileService.h:64
float getValue(int index, const ParticleType &particle, const std::vector< float > &auxVariables) const
std::vector< edm::EDGetTokenT< edm::ValueMap< int > > > mvaCatTokens_
std::vector< float > mvaValues_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const MultiTokenT< EcalRecHitCollection > ebRecHits_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< float > energyMatrix_
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
std::vector< int > mvaPasses_
const std::vector< std::string > valMapBranchNames_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< int > mvaCats_
ElectronMVANtuplizer(const edm::ParameterSet &)
edm::Handle< T > getValidHandle(const edm::Event &iEvent) const
Definition: MultiToken.h:95
ParameterDescriptionBase * add(U const &iLabel, T const &value)
int k[5][pyjets_maxn]
const std::vector< std::string > eleMapBranchNames_
bool fromHardProcessFinalState() const
Definition: GenParticle.h:76
const std::vector< float > getAuxVariables(edm::Ptr< ParticleType > const &particlePtr, const edm::Event &iEvent) const
std::vector< float > vars_
const MultiTokenT< std::vector< PileupSummaryInfo > > pileup_
MVAVariableManager< reco::GsfElectron > mvaVarMngr_
std::vector< edm::EDGetTokenT< edm::ValueMap< float > > > valMapTokens_
void analyze(const edm::Event &, const edm::EventSetup &) override
int matchToTruth(reco::GsfElectron const &electron, edm::View< reco::GenParticle > const &genParticles) const
edm::EventID id() const
Definition: EventBase.h:59
edm::Handle< T > getHandle(const edm::Event &iEvent) const
Definition: MultiToken.h:69
const MultiTokenT< EcalRecHitCollection > eeRecHits_
const MultiTokenT< std::vector< reco::Vertex > > vertices_
const std::vector< std::string > mvaCatTags_
std::vector< edm::EDGetTokenT< edm::ValueMap< bool > > > eleMapTokens_
const MultiTokenT< edm::View< reco::GsfElectron > > src_
const std::vector< std::string > mvaCatBranchNames_
const std::vector< std::string > eleMapTags_
const std::vector< std::string > valMapTags_