CMS 3D CMS Logo

HGCalTriggerNtupleGen.cc
Go to the documentation of this file.
5 
8 
15 
20 
21 // NOTE: most of this code is borrowed by https://github.com/CMS-HGCAL/reco-ntuples
22 // kudos goes to the original authors. Ideally the 2 repos should be merged since they share part of the use case
23 #include <memory>
24 
25 namespace HGCal_helpers {
26 
27  class Coordinates {
28  public:
29  Coordinates() : x(0), y(0), z(0), eta(0), phi(0) {}
30  float x, y, z, eta, phi;
32  };
33 
35  public:
36  SimpleTrackPropagator(const MagneticField *f) : field_(f), prod_(field_, alongMomentum), absz_target_(0) {
37  ROOT::Math::SMatrixIdentity id;
39  const float uncert = 0.001;
40  C *= uncert;
42  }
43  void setPropagationTargetZ(const float &z);
44 
45  bool propagate(const double px,
46  const double py,
47  const double pz,
48  const double x,
49  const double y,
50  const double z,
51  const float charge,
52  Coordinates &coords) const;
53 
54  bool propagate(const math::XYZTLorentzVectorD &momentum,
56  const float charge,
57  Coordinates &coords) const;
58 
59  private:
60  SimpleTrackPropagator() : field_(nullptr), prod_(field_, alongMomentum), absz_target_(0) {}
61  const RKPropagatorInS &RKProp() const { return prod_.propagator; }
66  float absz_target_;
67  };
68 
70  targetPlaneForward_ = Plane::build(Plane::PositionType(0, 0, std::abs(z)), Plane::RotationType());
71  targetPlaneBackward_ = Plane::build(Plane::PositionType(0, 0, -std::abs(z)), Plane::RotationType());
72  absz_target_ = std::abs(z);
73  }
75  const double py,
76  const double pz,
77  const double x,
78  const double y,
79  const double z,
80  const float charge,
81  Coordinates &output) const {
82  output = Coordinates();
83 
85  GlobalPoint startingPosition(x, y, z);
86  GlobalVector startingMomentum(px, py, pz);
88  TSOS startingStateP(
89  GlobalTrajectoryParameters(startingPosition, startingMomentum, charge, field_), err_, *startingPlane);
90 
91  TSOS trackStateP;
92  if (pz > 0) {
93  trackStateP = RKProp().propagate(startingStateP, *targetPlaneForward_);
94  } else {
95  trackStateP = RKProp().propagate(startingStateP, *targetPlaneBackward_);
96  }
97  if (trackStateP.isValid()) {
98  output.x = trackStateP.globalPosition().x();
99  output.y = trackStateP.globalPosition().y();
100  output.z = trackStateP.globalPosition().z();
101  output.phi = trackStateP.globalPosition().phi();
102  output.eta = trackStateP.globalPosition().eta();
103  return true;
104  }
105  return false;
106  }
107 
110  const float charge,
111  Coordinates &output) const {
112  return propagate(
113  momentum.px(), momentum.py(), momentum.pz(), position.x(), position.y(), position.z(), charge, output);
114  }
115 
116 } // namespace HGCal_helpers
117 
119 public:
121 
122  void initialize(TTree &, const edm::ParameterSet &, edm::ConsumesCollector &&) final;
123  void fill(const edm::Event &, const edm::EventSetup &) final;
124 
125  enum ReachHGCal { notReach = 0, outsideEESurface = 1, onEESurface = 2 };
126 
127 private:
128  void clear() final;
129 
132 
133  int gen_n_;
136 
137  float vtx_x_;
138  float vtx_y_;
139  float vtx_z_;
140 
142  // GenParticles
143  //
144  std::vector<float> genpart_eta_;
145  std::vector<float> genpart_phi_;
146  std::vector<float> genpart_pt_;
147  std::vector<float> genpart_energy_;
148  std::vector<float> genpart_dvx_;
149  std::vector<float> genpart_dvy_;
150  std::vector<float> genpart_dvz_;
151  std::vector<float> genpart_ovx_;
152  std::vector<float> genpart_ovy_;
153  std::vector<float> genpart_ovz_;
154  std::vector<float> genpart_exx_;
155  std::vector<float> genpart_exy_;
156  std::vector<int> genpart_mother_;
157  std::vector<float> genpart_exphi_;
158  std::vector<float> genpart_exeta_;
159  std::vector<float> genpart_fbrem_;
160  std::vector<int> genpart_pid_;
161  std::vector<int> genpart_gen_;
162  std::vector<int> genpart_reachedEE_;
163  std::vector<bool> genpart_fromBeamPipe_;
164  std::vector<std::vector<float>> genpart_posx_;
165  std::vector<std::vector<float>> genpart_posy_;
166  std::vector<std::vector<float>> genpart_posz_;
167 
169  // reco::GenParticles
170  //
171  std::vector<float> gen_eta_;
172  std::vector<float> gen_phi_;
173  std::vector<float> gen_pt_;
174  std::vector<float> gen_energy_;
175  std::vector<int> gen_charge_;
176  std::vector<int> gen_pdgid_;
177  std::vector<int> gen_status_;
178  std::vector<std::vector<int>> gen_daughters_;
179 
180  // -------convenient tool to deal with simulated tracks
181  std::unique_ptr<FSimEvent> mySimEvent_;
182 
183  // and also the magnetic field
185 
187 
188  // edm::EDGetTokenT<std::vector<reco::GenParticle> > genParticles_;
192 
195 };
196 
198 
200 
202  edm::ParameterSet particleFilter_(conf.getParameter<edm::ParameterSet>("particleFilter"));
203  mySimEvent_ = std::make_unique<FSimEvent>(particleFilter_);
204 
205  gen_token_ = collector.consumes<reco::GenParticleCollection>(conf.getParameter<edm::InputTag>("GenParticles"));
206  gen_PU_token_ = collector.consumes<std::vector<PileupSummaryInfo>>(conf.getParameter<edm::InputTag>("GenPU"));
207  tree.Branch("gen_n", &gen_n_, "gen_n/I");
208  tree.Branch("gen_PUNumInt", &gen_PUNumInt_, "gen_PUNumInt/I");
209  tree.Branch("gen_TrueNumInt", &gen_TrueNumInt_, "gen_TrueNumInt/F");
210 
211  hepmcev_token_ = collector.consumes<edm::HepMCProduct>(conf.getParameter<edm::InputTag>("MCEvent"));
212 
213  simTracks_token_ = collector.consumes<std::vector<SimTrack>>(conf.getParameter<edm::InputTag>("SimTracks"));
214  simVertices_token_ = collector.consumes<std::vector<SimVertex>>(conf.getParameter<edm::InputTag>("SimVertices"));
215 
216  tree.Branch("vtx_x", &vtx_x_);
217  tree.Branch("vtx_y", &vtx_y_);
218  tree.Branch("vtx_z", &vtx_z_);
219 
220  tree.Branch("gen_eta", &gen_eta_);
221  tree.Branch("gen_phi", &gen_phi_);
222  tree.Branch("gen_pt", &gen_pt_);
223  tree.Branch("gen_energy", &gen_energy_);
224  tree.Branch("gen_charge", &gen_charge_);
225  tree.Branch("gen_pdgid", &gen_pdgid_);
226  tree.Branch("gen_status", &gen_status_);
227  tree.Branch("gen_daughters", &gen_daughters_);
228 
229  tree.Branch("genpart_eta", &genpart_eta_);
230  tree.Branch("genpart_phi", &genpart_phi_);
231  tree.Branch("genpart_pt", &genpart_pt_);
232  tree.Branch("genpart_energy", &genpart_energy_);
233  tree.Branch("genpart_dvx", &genpart_dvx_);
234  tree.Branch("genpart_dvy", &genpart_dvy_);
235  tree.Branch("genpart_dvz", &genpart_dvz_);
236  tree.Branch("genpart_ovx", &genpart_ovx_);
237  tree.Branch("genpart_ovy", &genpart_ovy_);
238  tree.Branch("genpart_ovz", &genpart_ovz_);
239  tree.Branch("genpart_mother", &genpart_mother_);
240  tree.Branch("genpart_exphi", &genpart_exphi_);
241  tree.Branch("genpart_exeta", &genpart_exeta_);
242  tree.Branch("genpart_exx", &genpart_exx_);
243  tree.Branch("genpart_exy", &genpart_exy_);
244  tree.Branch("genpart_fbrem", &genpart_fbrem_);
245  tree.Branch("genpart_pid", &genpart_pid_);
246  tree.Branch("genpart_gen", &genpart_gen_);
247  tree.Branch("genpart_reachedEE", &genpart_reachedEE_);
248  tree.Branch("genpart_fromBeamPipe", &genpart_fromBeamPipe_);
249  tree.Branch("genpart_posx", &genpart_posx_);
250  tree.Branch("genpart_posy", &genpart_posy_);
251  tree.Branch("genpart_posz", &genpart_posz_);
252 }
253 
255  clear();
256 
258  iEvent.getByToken(gen_PU_token_, PupInfo_h);
259  const std::vector<PileupSummaryInfo> &PupInfo = *PupInfo_h;
260 
261  if (pdt_watcher_.check(es)) {
263  es.get<PDTRecord>().get(pdt);
264  mySimEvent_->initializePdt(&(*pdt));
265  }
266 
267  if (magfield_watcher_.check(es)) {
269  es.get<IdealMagneticFieldRecord>().get(magfield);
270  aField_ = &(*magfield);
271  }
272 
274 
275  // This balck magic is needed to use the mySimEvent_
277  edm::Handle<std::vector<SimTrack>> simTracksHandle;
278  edm::Handle<std::vector<SimVertex>> simVerticesHandle;
279 
280  iEvent.getByToken(hepmcev_token_, hevH);
281  iEvent.getByToken(simTracks_token_, simTracksHandle);
282  iEvent.getByToken(simVertices_token_, simVerticesHandle);
283  mySimEvent_->fill(*simTracksHandle, *simVerticesHandle);
284 
285  HepMC::GenVertex *primaryVertex = *(hevH)->GetEvent()->vertices_begin();
286  const float mm2cm = 0.1;
287  vtx_x_ = primaryVertex->position().x() * mm2cm; // to put in official units
288  vtx_y_ = primaryVertex->position().y() * mm2cm;
289  vtx_z_ = primaryVertex->position().z() * mm2cm;
290 
292  toHGCalPropagator.setPropagationTargetZ(triggerTools_.getLayerZ(1));
293  std::vector<FSimTrack *> allselectedgentracks;
294  const float eeInnerRadius = 25.;
295  const float eeOuterRadius = 160.;
296  unsigned int npart = mySimEvent_->nTracks();
297  for (unsigned int i = 0; i < npart; ++i) {
298  std::vector<float> xp, yp, zp;
299  FSimTrack &myTrack(mySimEvent_->track(i));
300  math::XYZTLorentzVectorD vtx(0, 0, 0, 0);
301 
302  int reachedEE = ReachHGCal::notReach; // compute the extrapolations for the particles reaching EE
303  // and for the gen particles
304  double fbrem = -1;
305 
306  if (std::abs(myTrack.vertex().position().z()) >= triggerTools_.getLayerZ(1))
307  continue;
308 
309  const unsigned nlayers = triggerTools_.lastLayerBH();
310  if (myTrack.noEndVertex()) // || myTrack.genpartIndex()>=0)
311  {
312  HGCal_helpers::Coordinates propcoords;
313  bool reachesHGCal =
314  toHGCalPropagator.propagate(myTrack.momentum(), myTrack.vertex().position(), myTrack.charge(), propcoords);
315  vtx = propcoords.toVector();
316 
317  if (reachesHGCal && vtx.Rho() < eeOuterRadius && vtx.Rho() > eeInnerRadius) {
318  reachedEE = ReachHGCal::onEESurface;
319  double dpt = 0;
320 
321  for (int i = 0; i < myTrack.nDaughters(); ++i)
322  dpt += myTrack.daughter(i).momentum().pt();
323  if (abs(myTrack.type()) == 11)
324  fbrem = dpt / myTrack.momentum().pt();
325  } else if (reachesHGCal && vtx.Rho() > eeOuterRadius)
326  reachedEE = ReachHGCal::outsideEESurface;
327 
328  HGCal_helpers::SimpleTrackPropagator indiv_particleProp(aField_);
329  for (unsigned il = 1; il <= nlayers; ++il) {
330  const float charge = myTrack.charge();
331  indiv_particleProp.setPropagationTargetZ(triggerTools_.getLayerZ(il));
332  HGCal_helpers::Coordinates propCoords;
333  indiv_particleProp.propagate(myTrack.momentum(), myTrack.vertex().position(), charge, propCoords);
334 
335  xp.push_back(propCoords.x);
336  yp.push_back(propCoords.y);
337  zp.push_back(propCoords.z);
338  }
339  } else {
340  vtx = myTrack.endVertex().position();
341  }
342  auto orig_vtx = myTrack.vertex().position();
343 
344  allselectedgentracks.push_back(&mySimEvent_->track(i));
345  // fill branches
346  genpart_eta_.push_back(myTrack.momentum().eta());
347  genpart_phi_.push_back(myTrack.momentum().phi());
348  genpart_pt_.push_back(myTrack.momentum().pt());
349  genpart_energy_.push_back(myTrack.momentum().energy());
350  genpart_dvx_.push_back(vtx.x());
351  genpart_dvy_.push_back(vtx.y());
352  genpart_dvz_.push_back(vtx.z());
353 
354  genpart_ovx_.push_back(orig_vtx.x());
355  genpart_ovy_.push_back(orig_vtx.y());
356  genpart_ovz_.push_back(orig_vtx.z());
357 
358  HGCal_helpers::Coordinates hitsHGCal;
359  toHGCalPropagator.propagate(myTrack.momentum(), orig_vtx, myTrack.charge(), hitsHGCal);
360 
361  genpart_exphi_.push_back(hitsHGCal.phi);
362  genpart_exeta_.push_back(hitsHGCal.eta);
363  genpart_exx_.push_back(hitsHGCal.x);
364  genpart_exy_.push_back(hitsHGCal.y);
365 
366  genpart_fbrem_.push_back(fbrem);
367  genpart_pid_.push_back(myTrack.type());
368  genpart_gen_.push_back(myTrack.genpartIndex());
369  genpart_reachedEE_.push_back(reachedEE);
370  genpart_fromBeamPipe_.push_back(true);
371 
372  genpart_posx_.push_back(xp);
373  genpart_posy_.push_back(yp);
374  genpart_posz_.push_back(zp);
375  }
376 
377  edm::Handle<std::vector<reco::GenParticle>> genParticlesHandle;
378  iEvent.getByToken(gen_token_, genParticlesHandle);
379  gen_n_ = genParticlesHandle->size();
380 
381  for (const auto &particle : *genParticlesHandle) {
382  gen_eta_.push_back(particle.eta());
383  gen_phi_.push_back(particle.phi());
384  gen_pt_.push_back(particle.pt());
385  gen_energy_.push_back(particle.energy());
386  gen_charge_.push_back(particle.charge());
387  gen_pdgid_.push_back(particle.pdgId());
388  gen_status_.push_back(particle.status());
389  std::vector<int> daughters(particle.daughterRefVector().size(), 0);
390  for (unsigned j = 0; j < particle.daughterRefVector().size(); ++j) {
391  daughters[j] = static_cast<int>(particle.daughterRefVector().at(j).key());
392  }
393  gen_daughters_.push_back(daughters);
394  }
395 
396  // associate gen particles to mothers
397  genpart_mother_.resize(genpart_posz_.size(), -1);
398  for (size_t i = 0; i < allselectedgentracks.size(); i++) {
399  const auto tracki = allselectedgentracks.at(i);
400 
401  for (size_t j = i + 1; j < allselectedgentracks.size(); j++) {
402  const auto trackj = allselectedgentracks.at(j);
403 
404  if (!tracki->noMother()) {
405  if (&tracki->mother() == trackj)
406  genpart_mother_.at(i) = j;
407  }
408  if (!trackj->noMother()) {
409  if (&trackj->mother() == tracki)
410  genpart_mother_.at(j) = i;
411  }
412  }
413  }
414 
415  for (const auto &PVI : PupInfo) {
416  if (PVI.getBunchCrossing() == 0) {
417  gen_PUNumInt_ = PVI.getPU_NumInteractions();
418  gen_TrueNumInt_ = PVI.getTrueNumInteractions();
419  }
420  }
421 }
422 
424  gen_n_ = 0;
425  gen_PUNumInt_ = 0;
426  gen_TrueNumInt_ = 0.;
427 
428  vtx_x_ = 0;
429  vtx_y_ = 0;
430  vtx_z_ = 0;
431 
432  //
433  genpart_eta_.clear();
434  genpart_phi_.clear();
435  genpart_pt_.clear();
436  genpart_energy_.clear();
437  genpart_dvx_.clear();
438  genpart_dvy_.clear();
439  genpart_dvz_.clear();
440  genpart_ovx_.clear();
441  genpart_ovy_.clear();
442  genpart_ovz_.clear();
443  genpart_exx_.clear();
444  genpart_exy_.clear();
445  genpart_mother_.clear();
446  genpart_exphi_.clear();
447  genpart_exeta_.clear();
448  genpart_fbrem_.clear();
449  genpart_pid_.clear();
450  genpart_gen_.clear();
451  genpart_reachedEE_.clear();
452  genpart_fromBeamPipe_.clear();
453  genpart_posx_.clear();
454  genpart_posy_.clear();
455  genpart_posz_.clear();
456 
458  // reco::GenParticles
459  //
460  gen_eta_.clear();
461  gen_phi_.clear();
462  gen_pt_.clear();
463  gen_energy_.clear();
464  gen_charge_.clear();
465  gen_pdgid_.clear();
466  gen_status_.clear();
467  gen_daughters_.clear();
468 }
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
static AlgebraicMatrix initialize()
const MagneticField * aField_
std::vector< int > genpart_mother_
void eventSetup(const edm::EventSetup &)
std::vector< std::vector< int > > gen_daughters_
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
#define nullptr
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
T y() const
Definition: PV3DBase.h:60
std::vector< std::vector< float > > genpart_posy_
GlobalPoint globalPosition() const
double npart
Definition: HydjetWrapper.h:46
edm::ESWatcher< PDTRecord > pdt_watcher_
std::vector< float > genpart_phi_
float getLayerZ(const unsigned &layerWithOffset) const
void initialize(TTree &, const edm::ParameterSet &, edm::ConsumesCollector &&) final
std::vector< float > gen_energy_
std::vector< float > genpart_exy_
std::unique_ptr< FSimEvent > mySimEvent_
edm::EDGetToken simVertices_token_
std::vector< float > gen_eta_
std::vector< std::vector< float > > genpart_posz_
int iEvent
Definition: GenABIO.cc:224
std::vector< int > gen_status_
std::vector< float > genpart_dvy_
std::vector< int > genpart_reachedEE_
std::vector< int > gen_pdgid_
std::vector< float > genpart_exx_
std::vector< float > gen_phi_
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
Definition: matutil.cc:151
static PlanePointer build(Args &&...args)
Definition: Plane.h:33
T z() const
Definition: PV3DBase.h:61
std::vector< int > genpart_pid_
void fill(const edm::Event &, const edm::EventSetup &) final
std::vector< int > gen_charge_
std::vector< bool > genpart_fromBeamPipe_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< float > genpart_fbrem_
std::vector< float > genpart_eta_
double f[11][100]
std::vector< float > genpart_pt_
std::vector< float > genpart_ovz_
const RKPropagatorInS & RKProp() const
unsigned lastLayerBH() const
edm::ESWatcher< IdealMagneticFieldRecord > magfield_watcher_
HGCalTriggerTools triggerTools_
TrajectoryStateOnSurface TSOS
Definition: TestHits.cc:19
std::vector< std::vector< float > > genpart_posx_
std::vector< float > genpart_ovy_
std::vector< float > gen_pt_
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
std::vector< float > genpart_exphi_
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:52
bool propagate(const double px, const double py, const double pz, const double x, const double y, const double z, const float charge, Coordinates &coords) const
T eta() const
Definition: PV3DBase.h:73
std::vector< float > genpart_energy_
math::XYZTLorentzVectorD toVector()
static int position[264][3]
Definition: ReadPGInfo.cc:289
T get() const
Definition: EventSetup.h:73
std::vector< float > genpart_ovx_
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::vector< float > genpart_exeta_
Definition: tree.py:1
HGCalTriggerNtupleGen(const edm::ParameterSet &)
std::vector< float > genpart_dvz_
std::vector< int > genpart_gen_
T x() const
Definition: PV3DBase.h:59
primaryVertex
hltOfflineBeamSpot for HLTMON
std::vector< float > genpart_dvx_