CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FBaseSimEvent.cc
Go to the documentation of this file.
1 //HepMC Headers
2 #include "HepMC/GenEvent.h"
3 #include "HepMC/GenVertex.h"
4 #include "HepMC/GenParticle.h"
5 
6 //Framework Headers
8 
9 //CMSSW Data Formats
12 
13 //FAMOS Headers
23 
25 
26 using namespace HepPDT;
27 
28 // system include
29 #include <iostream>
30 #include <iomanip>
31 #include <map>
32 #include <string>
33 
35  :
36  nSimTracks(0),
37  nSimVertices(0),
38  nGenParticles(0),
39  nChargedParticleTracks(0),
40  initialSize(5000),
41  random(0)
42 {
43 
45  theBeamSpot = math::XYZPoint(0.0,0.0,0.0);
46 
47  // Initialize the vectors of particles and vertices
48  theGenParticles = new std::vector<HepMC::GenParticle*>();
49  theSimTracks = new std::vector<FSimTrack>;
50  theSimVertices = new std::vector<FSimVertex>;
51  theChargedTracks = new std::vector<unsigned>();
53 
54  // Reserve some size to avoid mutiple copies
55  /* */
56  theSimTracks->resize(initialSize);
57  theSimVertices->resize(initialSize);
60  theFSimVerticesType->resize(initialSize);
65  /* */
66 
67  // Initialize the Particle filter
68  myFilter = new KineParticleFilter(kine);
69 
70 }
71 
73  const edm::ParameterSet& kine,
74  const RandomEngine* engine)
75  :
76  nSimTracks(0),
77  nSimVertices(0),
78  nGenParticles(0),
79  nChargedParticleTracks(0),
80  initialSize(5000),
81  theVertexGenerator(0),
82  random(engine)
83 {
84 
85  // Initialize the vertex generator
86  std::string vtxType = vtx.getParameter<std::string>("type");
87  if ( vtxType == "Gaussian" )
89  else if ( vtxType == "Flat" )
91  else if ( vtxType == "BetaFunc" )
93  else
95  // Initialize the beam spot, if not read from the DataBase
96  theBeamSpot = math::XYZPoint(0.0,0.0,0.0);
97 
98  // Initialize the distance from (0,0,0) after which *generated* particles are
99  // no longer considered - because the mother could have interacted before.
100  // unit : cm x cm
101  lateVertexPosition = 2.5*2.5;
102 
103  // Initialize the vectors of particles and vertices
104  theGenParticles = new std::vector<HepMC::GenParticle*>();
105  theSimTracks = new std::vector<FSimTrack>;
106  theSimVertices = new std::vector<FSimVertex>;
107  theChargedTracks = new std::vector<unsigned>();
109 
110  // Reserve some size to avoid mutiple copies
111  /* */
112  theSimTracks->resize(initialSize);
113  theSimVertices->resize(initialSize);
114  theGenParticles->resize(initialSize);
115  theChargedTracks->resize(initialSize);
116  theFSimVerticesType->resize(initialSize);
121  /* */
122 
123  // Initialize the Particle filter
124  myFilter = new KineParticleFilter(kine);
125 
126 }
127 
129 
130  // Clear the vectors
131  theGenParticles->clear();
132  theSimTracks->clear();
133  theSimVertices->clear();
134  theChargedTracks->clear();
135  theFSimVerticesType->clear();
136 
137  // Delete
138  delete theGenParticles;
139  delete theSimTracks;
140  delete theSimVertices;
141  delete theChargedTracks;
142  delete theFSimVerticesType;
143  delete myFilter;
144 
145 }
146 
147 void
149 
150  pdt = aPdt;
151 
152 }
153 
154 /*
155 const HepPDT::ParticleDataTable*
156 FBaseSimEvent::theTable() const {
157  return pdt;
158 }
159 */
160 
161 void
162 FBaseSimEvent::fill(const HepMC::GenEvent& myGenEvent) {
163 
164  // Clear old vectors
165  clear();
166 
167  // Add the particles in the FSimEvent
168  addParticles(myGenEvent);
169 
170  /*
171  std::cout << "The MC truth! " << std::endl;
172  printMCTruth(myGenEvent);
173 
174  std::cout << std::endl << "The FAMOS event! " << std::endl;
175  print();
176  */
177 
178 }
179 
180 void
182 
183  // Clear old vectors
184  clear();
185 
186  // Add the particles in the FSimEvent
187  addParticles(myGenParticles);
188 
189 }
190 
191 void
192 FBaseSimEvent::fill(const std::vector<SimTrack>& simTracks,
193  const std::vector<SimVertex>& simVertices) {
194 
195  // Watch out there ! A SimVertex is in mm (stupid),
196  // while a FSimVertex is in cm (clever).
197 
198  clear();
199 
200  unsigned nVtx = simVertices.size();
201  unsigned nTks = simTracks.size();
202 
203  // Empty event, do nothin'
204  if ( nVtx == 0 ) return;
205 
206  // Two arrays for internal use.
207  std::vector<int> myVertices(nVtx,-1);
208  std::vector<int> myTracks(nTks,-1);
209 
210  // create a map associating geant particle id and position in the
211  // event SimTrack vector
212 
213  std::map<unsigned, unsigned> geantToIndex;
214  for( unsigned it=0; it<simTracks.size(); ++it ) {
215  geantToIndex[ simTracks[it].trackId() ] = it;
216  }
217 
218  // Create also a map associating a SimTrack with its endVertex
219  /*
220  std::map<unsigned, unsigned> endVertex;
221  for ( unsigned iv=0; iv<simVertices.size(); ++iv ) {
222  endVertex[ simVertices[iv].parentIndex() ] = iv;
223  }
224  */
225 
226  // Set the main vertex for the kine particle filter
227  // SimVertices were in mm until 110_pre2
228  // HepLorentzVector primaryVertex = simVertices[0].position()/10.;
229  // SImVertices are now in cm
230  // Also : position is copied until SimVertex switches to Mathcore.
231  // XYZTLorentzVector primaryVertex = simVertices[0].position();
232  // The next 5 lines to be then replaced by the previous line
233  XYZTLorentzVector primaryVertex(simVertices[0].position().x(),
234  simVertices[0].position().y(),
235  simVertices[0].position().z(),
236  simVertices[0].position().t());
237  //
238  myFilter->setMainVertex(primaryVertex);
239  // Add the main vertex to the list.
241  myVertices[0] = 0;
242 
243  for( unsigned trackId=0; trackId<nTks; ++trackId ) {
244 
245  // The track
246  const SimTrack& track = simTracks[trackId];
247  // std::cout << std::endl << "SimTrack " << trackId << " " << track << std::endl;
248 
249  // The origin vertex
250  int vertexId = track.vertIndex();
251  const SimVertex& vertex = simVertices[vertexId];
252  //std::cout << "Origin vertex " << vertexId << " " << vertex << std::endl;
253 
254  // The mother track
255  int motherId = -1;
256  if( !vertex.noParent() ) { // there is a parent to this vertex
257  // geant id of the mother
258  unsigned motherGeantId = vertex.parentIndex();
259  std::map<unsigned, unsigned >::iterator association
260  = geantToIndex.find( motherGeantId );
261  if(association != geantToIndex.end() )
262  motherId = association->second;
263  }
264  int originId = motherId == - 1 ? -1 : myTracks[motherId];
265  //std::cout << "Origin id " << originId << std::endl;
266 
267  /*
268  if ( endVertex.find(trackId) != endVertex.end() )
269  std::cout << "End vertex id = " << endVertex[trackId] << std::endl;
270  else
271  std::cout << "No endVertex !!! " << std::endl;
272  std::cout << "Tracker surface position " << track.trackerSurfacePosition() << std::endl;
273  */
274 
275  // Add the vertex (if it does not already exist!)
276  XYZTLorentzVector position(vertex.position().px(),vertex.position().py(),
277  vertex.position().pz(),vertex.position().e());
278  if ( myVertices[vertexId] == -1 )
279  // Momentum and position are copied until SimTrack and SimVertex
280  // switch to Mathcore.
281  // myVertices[vertexId] = addSimVertex(vertex.position(),originId);
282  // The next line to be then replaced by the previous line
283  myVertices[vertexId] = addSimVertex(position,originId);
284 
285  // Add the track (with protection for brem'ing electrons and muons)
286  int motherType = motherId == -1 ? 0 : simTracks[motherId].type();
287 
288  bool notBremInDetector =
289  (abs(motherType) != 11 && abs(motherType) != 13) ||
290  motherType != track.type() ||
291  position.Perp2() < lateVertexPosition ;
292 
293  if ( notBremInDetector ) {
294  // Momentum and position are copied until SimTrack and SimVertex
295  // switch to Mathcore.
296  // RawParticle part(track.momentum(), vertex.position());
297  // The next 3 lines to be then replaced by the previous line
298  XYZTLorentzVector momentum(track.momentum().px(),track.momentum().py(),
299  track.momentum().pz(),track.momentum().e());
300  RawParticle part(momentum,position);
301  //
302  part.setID(track.type());
303  //std::cout << "Ctau = " << part.PDGcTau() << std::endl;
304  // Don't save tracks that have decayed immediately but for which no daughters
305  // were saved (probably due to cuts on E, pT and eta)
306  // if ( part.PDGcTau() > 0.1 || endVertex.find(trackId) != endVertex.end() )
307  myTracks[trackId] = addSimTrack(&part,myVertices[vertexId],track.genpartIndex());
308  if ( myTracks[trackId] >= 0 ) {
309  (*theSimTracks)[ myTracks[trackId] ].setTkPosition(track.trackerSurfacePosition());
310  (*theSimTracks)[ myTracks[trackId] ].setTkMomentum(track.trackerSurfaceMomentum());
311  }
312  } else {
313 
314  myTracks[trackId] = myTracks[motherId];
315  if ( myTracks[trackId] >= 0 ) {
316  (*theSimTracks)[ myTracks[trackId] ].setTkPosition(track.trackerSurfacePosition());
317  (*theSimTracks)[ myTracks[trackId] ].setTkMomentum(track.trackerSurfaceMomentum());
318  }
319  }
320 
321  }
322 
323  // Now loop over the remaining end vertices !
324  for( unsigned vertexId=0; vertexId<nVtx; ++vertexId ) {
325 
326  // if the vertex is already saved, just ignore.
327  if ( myVertices[vertexId] != -1 ) continue;
328 
329  // The yet unused vertex
330  const SimVertex& vertex = simVertices[vertexId];
331 
332  // The mother track
333  int motherId = -1;
334  if( !vertex.noParent() ) { // there is a parent to this vertex
335 
336  // geant id of the mother
337  unsigned motherGeantId = vertex.parentIndex();
338  std::map<unsigned, unsigned >::iterator association
339  = geantToIndex.find( motherGeantId );
340  if(association != geantToIndex.end() )
341  motherId = association->second;
342  }
343  int originId = motherId == - 1 ? -1 : myTracks[motherId];
344 
345  // Add the vertex
346  // Momentum and position are copied until SimTrack and SimVertex
347  // switch to Mathcore.
348  // myVertices[vertexId] = addSimVertex(vertex.position(),originId);
349  // The next 3 lines to be then replaced by the previous line
350  XYZTLorentzVector position(vertex.position().px(),vertex.position().py(),
351  vertex.position().pz(),vertex.position().e());
352  myVertices[vertexId] = addSimVertex(position,originId);
353  }
354 
355  // Finally, propagate all particles to the calorimeters
356  BaseParticlePropagator myPart;
357  XYZTLorentzVector mom;
359 
360 
361  // Loop over the tracks
362  for( int fsimi=0; fsimi < (int)nTracks() ; ++fsimi) {
363 
364 
365  FSimTrack& myTrack = track(fsimi);
366  double trackerSurfaceTime = myTrack.vertex().position().t()
367  + myTrack.momentum().e()/myTrack.momentum().pz()
368  * ( myTrack.trackerSurfacePosition().z()
369  - myTrack.vertex().position().z() );
370  pos = XYZTLorentzVector(myTrack.trackerSurfacePosition().x(),
371  myTrack.trackerSurfacePosition().y(),
372  myTrack.trackerSurfacePosition().z(),
373  trackerSurfaceTime);
374  mom = XYZTLorentzVector(myTrack.trackerSurfaceMomentum().x(),
375  myTrack.trackerSurfaceMomentum().y(),
376  myTrack.trackerSurfaceMomentum().z(),
377  myTrack.trackerSurfaceMomentum().t());
378 
379  if ( mom.T() > 0. ) {
380  // The particle to be propagated
381  myPart = BaseParticlePropagator(RawParticle(mom,pos),0.,0.,4.);
382  myPart.setCharge(myTrack.charge());
383 
384  // Propagate to Preshower layer 1
385  myPart.propagateToPreshowerLayer1(false);
386  if ( myTrack.notYetToEndVertex(myPart.vertex()) && myPart.getSuccess()>0 )
387  myTrack.setLayer1(myPart,myPart.getSuccess());
388 
389  // Propagate to Preshower Layer 2
390  myPart.propagateToPreshowerLayer2(false);
391  if ( myTrack.notYetToEndVertex(myPart.vertex()) && myPart.getSuccess()>0 )
392  myTrack.setLayer2(myPart,myPart.getSuccess());
393 
394  // Propagate to Ecal Endcap
395  myPart.propagateToEcalEntrance(false);
396  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
397  myTrack.setEcal(myPart,myPart.getSuccess());
398 
399  // Propagate to HCAL entrance
400  myPart.propagateToHcalEntrance(false);
401  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
402  myTrack.setHcal(myPart,myPart.getSuccess());
403 
404  // Attempt propagation to HF for low pt and high eta
405  if ( myPart.cos2ThetaV()>0.8 || mom.T() < 3. ) {
406  // Propagate to VFCAL entrance
407  myPart.propagateToVFcalEntrance(false);
408  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
409  myTrack.setVFcal(myPart,myPart.getSuccess());
410 
411  // Otherwise propagate to the HCAL exit and HO.
412  } else {
413  // Propagate to HCAL exit
414  myPart.propagateToHcalExit(false);
415  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
416  myTrack.setHcalExit(myPart,myPart.getSuccess());
417  // Propagate to HOLayer entrance
418  myPart.setMagneticField(0);
419  myPart.propagateToHOLayer(false);
420  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
421  myTrack.setHO(myPart,myPart.getSuccess());
422  }
423  }
424  }
425 }
426 
427 
428 void
429 FBaseSimEvent::addParticles(const HepMC::GenEvent& myGenEvent) {
430 
432  int genEventSize = myGenEvent.particles_size();
433  std::vector<int> myGenVertices(genEventSize, static_cast<int>(0));
434 
435  // If no particles, no work to be done !
436  if ( myGenEvent.particles_empty() ) return;
437 
438  // Are there particles in the FSimEvent already ?
439  int offset = nGenParts();
440 
441  // Primary vertex (already smeared by the SmearedVtx module)
442  HepMC::GenVertex* primaryVertex = *(myGenEvent.vertices_begin());
443 
444  // Beginning of workaround a bug in pythia particle gun
445  unsigned primaryMother = primaryVertex->particles_in_size();
446  if ( primaryMother ) {
447  unsigned partId = (*(primaryVertex->particles_in_const_begin()))->pdg_id();
448  if ( abs(partId) == 2212 ) primaryMother = 0;
449  }
450  // End of workaround a bug in pythia particle gun
451 
452  XYZTLorentzVector primaryVertexPosition(primaryVertex->position().x()/10.,
453  primaryVertex->position().y()/10.,
454  primaryVertex->position().z()/10.,
455  primaryVertex->position().t()/10.);
456  // Actually this is the true end of the workaround
457  primaryVertexPosition *= (1-primaryMother);
458  // THE END.
459 
460  // Smear the main vertex if needed
461  // Now takes the origin from the database
462  XYZTLorentzVector smearedVertex;
463  if ( primaryVertexPosition.Vect().Mag2() < 1E-16 ) {
465  smearedVertex = XYZTLorentzVector(
469  0.);
470  }
471 
472  // Set the main vertex
473  myFilter->setMainVertex(primaryVertexPosition+smearedVertex);
474 
475  // This is the smeared main vertex
476  int mainVertex = addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
477 
478  HepMC::GenEvent::particle_const_iterator piter;
479  HepMC::GenEvent::particle_const_iterator pbegin = myGenEvent.particles_begin();
480  HepMC::GenEvent::particle_const_iterator pend = myGenEvent.particles_end();
481 
482  int initialBarcode = 0;
483  if ( pbegin != pend ) initialBarcode = (*pbegin)->barcode();
484  // Loop on the particles of the generated event
485  for ( piter = pbegin; piter != pend; ++piter ) {
486 
487  // This is the generated particle pointer - for the signal event only
488  HepMC::GenParticle* p = *piter;
489 
490  if ( !offset ) {
491  (*theGenParticles)[nGenParticles++] = p;
493  theGenSize *= 2;
494  theGenParticles->resize(theGenSize);
495  }
496 
497  }
498 
499  // Reject particles with late origin vertex (i.e., coming from late decays)
500  // This should not happen, but one never knows what users may be up to!
501  // For example exotic particles might decay late - keep the decay products in the case.
502  XYZTLorentzVector productionVertexPosition(0.,0.,0.,0.);
503  HepMC::GenVertex* productionVertex = p->production_vertex();
504  if ( productionVertex ) {
505  unsigned productionMother = productionVertex->particles_in_size();
506  if ( productionMother ) {
507  unsigned motherId = (*(productionVertex->particles_in_const_begin()))->pdg_id();
508  if ( abs(motherId) < 1000000 )
509  productionVertexPosition =
510  XYZTLorentzVector(productionVertex->position().x()/10.,
511  productionVertex->position().y()/10.,
512  productionVertex->position().z()/10.,
513  productionVertex->position().t()/10.) + smearedVertex;
514  }
515  }
516  if ( !myFilter->accept(productionVertexPosition) ) continue;
517 
518  int abspdgId = abs(p->pdg_id());
519  HepMC::GenVertex* endVertex = p->end_vertex();
520 
521  // Keep only:
522  // 1) Stable particles (watch out! New status code = 1001!)
523  bool testStable = p->status()%1000==1;
524  // Declare stable standard particles that decay after a macroscopic path length
525  // (except if exotic)
526  if ( p->status() == 2 && abspdgId < 1000000) {
527  if ( endVertex ) {
528  XYZTLorentzVector decayPosition =
529  XYZTLorentzVector(endVertex->position().x()/10.,
530  endVertex->position().y()/10.,
531  endVertex->position().z()/10.,
532  endVertex->position().t()/10.) + smearedVertex;
533  // If the particle flew enough to be beyond the beam pipe enveloppe, just declare it stable
534  if ( decayPosition.Perp2() > lateVertexPosition ) testStable = true;
535  }
536  }
537 
538  // 2) or particles with stable daughters (watch out! New status code = 1001!)
539  bool testDaugh = false;
540  if ( !testStable &&
541  p->status() == 2 &&
542  endVertex &&
543  endVertex->particles_out_size() ) {
544  HepMC::GenVertex::particles_out_const_iterator firstDaughterIt =
545  endVertex->particles_out_const_begin();
546  HepMC::GenVertex::particles_out_const_iterator lastDaughterIt =
547  endVertex->particles_out_const_end();
548  for ( ; firstDaughterIt != lastDaughterIt ; ++firstDaughterIt ) {
549  HepMC::GenParticle* daugh = *firstDaughterIt;
550  if ( daugh->status()%1000==1 ) {
551  // Check that it is not a "prompt electron or muon brem":
552  if (abspdgId == 11 || abspdgId == 13) {
553  if ( endVertex ) {
554  XYZTLorentzVector endVertexPosition = XYZTLorentzVector(endVertex->position().x()/10.,
555  endVertex->position().y()/10.,
556  endVertex->position().z()/10.,
557  endVertex->position().t()/10.);
558  // If the particle flew enough to be beyond the beam pipe enveloppe, just declare it stable
559  if ( endVertexPosition.Perp2() < lateVertexPosition ) {
560  break;
561  }
562  }
563  }
564  testDaugh=true;
565  break;
566  }
567  }
568  }
569 
570  // 3) or particles that fly more than one micron.
571  double dist = 0.;
572  if ( !testStable && !testDaugh && p->production_vertex() ) {
574  productionVertexPosition(p->production_vertex()->position().x()/10.,
575  p->production_vertex()->position().y()/10.,
576  p->production_vertex()->position().z()/10.,
577  p->production_vertex()->position().t()/10.);
578  dist = (primaryVertexPosition-productionVertexPosition).Vect().Mag2();
579  }
580  bool testDecay = ( dist > 1e-8 ) ? true : false;
581 
582  // Save the corresponding particle and vertices
583  if ( testStable || testDaugh || testDecay ) {
584 
585  /*
586  const HepMC::GenParticle* mother = p->production_vertex() ?
587  *(p->production_vertex()->particles_in_const_begin()) : 0;
588  */
589 
590  int motherBarcode = p->production_vertex() &&
591  p->production_vertex()->particles_in_const_begin() !=
592  p->production_vertex()->particles_in_const_end() ?
593  (*(p->production_vertex()->particles_in_const_begin()))->barcode() : 0;
594 
595  int originVertex =
596  motherBarcode && myGenVertices[motherBarcode-initialBarcode] ?
597  myGenVertices[motherBarcode-initialBarcode] : mainVertex;
598 
599  XYZTLorentzVector momentum(p->momentum().px(),
600  p->momentum().py(),
601  p->momentum().pz(),
602  p->momentum().e());
603  RawParticle part(momentum, vertex(originVertex).position());
604  part.setID(p->pdg_id());
605 
606  // Add the particle to the event and to the various lists
607 
608  int theTrack = testStable && p->end_vertex() ?
609  // The particle is scheduled to decay
610  addSimTrack(&part,originVertex, nGenParts()-offset,p->end_vertex()) :
611  // The particle is not scheduled to decay
612  addSimTrack(&part,originVertex, nGenParts()-offset);
613 
614  if (
615  // This one deals with particles with no end vertex
616  !p->end_vertex() ||
617  // This one deals with particles that have a pre-defined
618  // decay proper time, but have not decayed yet
619  ( testStable && p->end_vertex() && !p->end_vertex()->particles_out_size() )
620  // In both case, just don't add a end vertex in the FSimEvent
621  ) continue;
622 
623  // Add the vertex to the event and to the various lists
624  XYZTLorentzVector decayVertex =
625  XYZTLorentzVector(p->end_vertex()->position().x()/10.,
626  p->end_vertex()->position().y()/10.,
627  p->end_vertex()->position().z()/10.,
628  p->end_vertex()->position().t()/10.) +
629  smearedVertex;
630  // vertex(mainVertex).position();
631  int theVertex = addSimVertex(decayVertex,theTrack, FSimVertexType::DECAY_VERTEX);
632 
633  if ( theVertex != -1 ) myGenVertices[p->barcode()-initialBarcode] = theVertex;
634 
635  // There we are !
636  }
637  }
638 
639 }
640 
641 void
643 
644  // If no particles, no work to be done !
645  unsigned int nParticles = myGenParticles.size();
647 
648  if ( !nParticles ) return;
649 
651  std::map<const reco::Candidate*,int> myGenVertices;
652 
653  // Are there particles in the FSimEvent already ?
654  int offset = nTracks();
655 
656  // Skip the incoming protons
657  nGenParticles = 0;
658  unsigned int ip = 0;
659  if ( nParticles > 1 &&
660  myGenParticles[0].pdgId() == 2212 &&
661  myGenParticles[1].pdgId() == 2212 ) {
662  ip = 2;
663  nGenParticles = 2;
664  }
665 
666  // Primary vertex (already smeared by the SmearedVtx module)
667  XYZTLorentzVector primaryVertex (myGenParticles[ip].vx(),
668  myGenParticles[ip].vy(),
669  myGenParticles[ip].vz(),
670  0.);
671 
672  // Smear the main vertex if needed
673  XYZTLorentzVector smearedVertex;
674  if ( primaryVertex.mag() < 1E-8 ) {
676  smearedVertex = XYZTLorentzVector(
680  0.);
681  }
682 
683  // Set the main vertex
684  myFilter->setMainVertex(primaryVertex+smearedVertex);
685 
686  // This is the smeared main vertex
687  int mainVertex = addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
688 
689  // Loop on the particles of the generated event
690  for ( ; ip<nParticles; ++ip ) {
691 
692  // nGenParticles = ip;
693 
694  nGenParticles++;
695  const reco::GenParticle& p = myGenParticles[ip];
696 
697  // Reject particles with late origin vertex (i.e., coming from late decays)
698  // This should not happen, but one never knows what users may be up to!
699  // For example exotic particles might decay late - keep the decay products in the case.
700  XYZTLorentzVector productionVertexPosition(0.,0.,0.,0.);
701  const reco::Candidate* productionMother = p.numberOfMothers() ? p.mother(0) : 0;
702  if ( productionMother ) {
703  unsigned motherId = productionMother->pdgId();
704  if ( abs(motherId) < 1000000 )
705  productionVertexPosition = XYZTLorentzVector(p.vx(), p.vy(), p.vz(), 0.) + smearedVertex;
706  }
707  if ( !myFilter->accept(productionVertexPosition) ) continue;
708 
709  // Keep only:
710  // 1) Stable particles
711  bool testStable = p.status()%1000==1;
712  // Declare stable standard particles that decay after a macroscopic path length
713  // (except if exotic particle)
714  if ( p.status() == 2 && abs(p.pdgId()) < 1000000 ) {
715  unsigned int nDaughters = p.numberOfDaughters();
716  if ( nDaughters ) {
717  const reco::Candidate* daughter = p.daughter(0);
718  XYZTLorentzVector decayPosition =
719  XYZTLorentzVector(daughter->vx(), daughter->vy(), daughter->vz(), 0.) + smearedVertex;
720  // If the particle flew enough to be beyond the beam pipe enveloppe, just declare it stable
721  if ( decayPosition.Perp2() > lateVertexPosition ) testStable = true;
722  }
723  }
724 
725  // 2) or particles with stable daughters
726  bool testDaugh = false;
727  unsigned int nDaughters = p.numberOfDaughters();
728  if ( !testStable &&
729  // p.status() == 2 &&
730  nDaughters ) {
731  for ( unsigned iDaughter=0; iDaughter<nDaughters; ++iDaughter ) {
732  const reco::Candidate* daughter = p.daughter(iDaughter);
733  if ( daughter->status()%1000==1 ) {
734  testDaugh=true;
735  break;
736  }
737  }
738  }
739 
740  // 3) or particles that fly more than one micron.
741  double dist = 0.;
742  if ( !testStable && !testDaugh ) {
743  XYZTLorentzVector productionVertex(p.vx(),p.vy(),p.vz(),0.);
744  dist = (primaryVertex-productionVertex).Vect().Mag2();
745  }
746  bool testDecay = ( dist > 1e-8 ) ? true : false;
747 
748  // Save the corresponding particle and vertices
749  if ( testStable || testDaugh || testDecay ) {
750 
751  const reco::Candidate* mother = p.numberOfMothers() ? p.mother(0) : 0;
752 
753  int originVertex =
754  mother &&
755  myGenVertices.find(mother) != myGenVertices.end() ?
756  myGenVertices[mother] : mainVertex;
757 
758  XYZTLorentzVector momentum(p.px(),p.py(),p.pz(),p.energy());
759  RawParticle part(momentum, vertex(originVertex).position());
760  part.setID(p.pdgId());
761 
762  // Add the particle to the event and to the various lists
763  int theTrack = addSimTrack(&part,originVertex, nGenParts()-offset);
764 
765  // It there an end vertex ?
766  if ( !nDaughters ) continue;
767  const reco::Candidate* daughter = p.daughter(0);
768 
769  // Add the vertex to the event and to the various lists
770  XYZTLorentzVector decayVertex =
771  XYZTLorentzVector(daughter->vx(), daughter->vy(),
772  daughter->vz(), 0.) + smearedVertex;
773  int theVertex = addSimVertex(decayVertex,theTrack, FSimVertexType::DECAY_VERTEX);
774 
775  if ( theVertex != -1 ) myGenVertices[&p] = theVertex;
776 
777  // There we are !
778  }
779  }
780 
781  // There is no GenParticle's in that case...
782  // nGenParticles=0;
783 
784 }
785 
786 int
787 FBaseSimEvent::addSimTrack(const RawParticle* p, int iv, int ig,
788  const HepMC::GenVertex* ev) {
789 
790  // Check that the particle is in the Famos "acceptance"
791  // Keep all primaries of pile-up events, though
792  if ( !myFilter->accept(p) && ig >= -1 ) return -1;
793 
794  // The new track index
795  int trackId = nSimTracks++;
797  theTrackSize *= 2;
798  theSimTracks->resize(theTrackSize);
799  }
800 
801  // Attach the particle to the origin vertex, and to the mother
802  vertex(iv).addDaughter(trackId);
803  if ( !vertex(iv).noParent() ) {
804  track(vertex(iv).parent().id()).addDaughter(trackId);
805 
806  if ( ig == -1 ) {
807  int motherId = track(vertex(iv).parent().id()).genpartIndex();
808  if ( motherId < -1 ) ig = motherId;
809  }
810  }
811 
812  // Some transient information for FAMOS internal use
813  (*theSimTracks)[trackId] = ev ?
814  // A proper decay time is scheduled
815  FSimTrack(p,iv,ig,trackId,this,
816  ev->position().t()/10.
817  * p->PDGmass()
818  / std::sqrt(p->momentum().Vect().Mag2())) :
819  // No proper decay time is scheduled
820  FSimTrack(p,iv,ig,trackId,this);
821 
822  return trackId;
823 
824 }
825 
826 int
828 
829  // Check that the vertex is in the Famos "acceptance"
830  if ( !myFilter->accept(v) ) return -1;
831 
832  // The number of vertices
833  int vertexId = nSimVertices++;
835  theVertexSize *= 2;
836  theSimVertices->resize(theVertexSize);
838  }
839 
840  // Attach the end vertex to the particle (if accepted)
841  if ( im !=-1 ) track(im).setEndVertex(vertexId);
842 
843  // Some transient information for FAMOS internal use
844  (*theSimVertices)[vertexId] = FSimVertex(v,im,vertexId,this);
845 
846  (*theFSimVerticesType)[vertexId] = FSimVertexType(type);
847 
848  return vertexId;
849 
850 }
851 
852 void
853 FBaseSimEvent::printMCTruth(const HepMC::GenEvent& myGenEvent) {
854 
855  std::cout << "Id Gen Name eta phi pT E Vtx1 "
856  << " x y z "
857  << "Moth Vtx2 eta phi R Z Da1 Da2 Ecal?" << std::endl;
858 
859  for ( HepMC::GenEvent::particle_const_iterator
860  piter = myGenEvent.particles_begin();
861  piter != myGenEvent.particles_end();
862  ++piter ) {
863 
864  HepMC::GenParticle* p = *piter;
865  /* */
866  int partId = p->pdg_id();
868 
869  if ( pdt->particle(ParticleID(partId)) !=0 ) {
870  name = (pdt->particle(ParticleID(partId)))->name();
871  } else {
872  name = "none";
873  }
874 
875  XYZTLorentzVector momentum1(p->momentum().px(),
876  p->momentum().py(),
877  p->momentum().pz(),
878  p->momentum().e());
879 
880  int vertexId1 = 0;
881 
882  if ( !p->production_vertex() ) continue;
883 
884  XYZVector vertex1 (p->production_vertex()->position().x()/10.,
885  p->production_vertex()->position().y()/10.,
886  p->production_vertex()->position().z()/10.);
887  vertexId1 = p->production_vertex()->barcode();
888 
889  std::cout.setf(std::ios::fixed, std::ios::floatfield);
890  std::cout.setf(std::ios::right, std::ios::adjustfield);
891 
892  std::cout << std::setw(4) << p->barcode() << " "
893  << name;
894 
895  for(unsigned int k=0;k<11-name.length() && k<12; k++) std::cout << " ";
896 
897  double eta = momentum1.eta();
898  if ( eta > +10. ) eta = +10.;
899  if ( eta < -10. ) eta = -10.;
900  std::cout << std::setw(6) << std::setprecision(2) << eta << " "
901  << std::setw(6) << std::setprecision(2) << momentum1.phi() << " "
902  << std::setw(7) << std::setprecision(2) << momentum1.pt() << " "
903  << std::setw(7) << std::setprecision(2) << momentum1.e() << " "
904  << std::setw(4) << vertexId1 << " "
905  << std::setw(6) << std::setprecision(1) << vertex1.x() << " "
906  << std::setw(6) << std::setprecision(1) << vertex1.y() << " "
907  << std::setw(6) << std::setprecision(1) << vertex1.z() << " ";
908 
909  const HepMC::GenParticle* mother =
910  *(p->production_vertex()->particles_in_const_begin());
911 
912  if ( mother )
913  std::cout << std::setw(4) << mother->barcode() << " ";
914  else
915  std::cout << " " ;
916 
917  if ( p->end_vertex() ) {
918  XYZTLorentzVector vertex2(p->end_vertex()->position().x()/10.,
919  p->end_vertex()->position().y()/10.,
920  p->end_vertex()->position().z()/10.,
921  p->end_vertex()->position().t()/10.);
922  int vertexId2 = p->end_vertex()->barcode();
923 
924  std::vector<const HepMC::GenParticle*> children;
925  HepMC::GenVertex::particles_out_const_iterator firstDaughterIt =
926  p->end_vertex()->particles_out_const_begin();
927  HepMC::GenVertex::particles_out_const_iterator lastDaughterIt =
928  p->end_vertex()->particles_out_const_end();
929  for ( ; firstDaughterIt != lastDaughterIt ; ++firstDaughterIt ) {
930  children.push_back(*firstDaughterIt);
931  }
932 
933  std::cout << std::setw(4) << vertexId2 << " "
934  << std::setw(6) << std::setprecision(2) << vertex2.eta() << " "
935  << std::setw(6) << std::setprecision(2) << vertex2.phi() << " "
936  << std::setw(5) << std::setprecision(1) << vertex2.pt() << " "
937  << std::setw(6) << std::setprecision(1) << vertex2.z() << " ";
938  for ( unsigned id=0; id<children.size(); ++id )
939  std::cout << std::setw(4) << children[id]->barcode() << " ";
940  }
941  std::cout << std::endl;
942 
943  }
944 
945 }
946 
947 void
949 
950  std::cout << " Id Gen Name eta phi pT E Vtx1 "
951  << " x y z "
952  << "Moth Vtx2 eta phi R Z Daughters Ecal?" << std::endl;
953 
954  for( int i=0; i<(int)nTracks(); i++ )
955  std::cout << track(i) << std::endl;
956 
957  for( int i=0; i<(int)nVertices(); i++ )
958  std::cout << "i = " << i << " " << vertexType(i) << std::endl;
959 
960 
961 
962 }
963 
964 void
966 
967  nSimTracks = 0;
968  nSimVertices = 0;
969  nGenParticles = 0;
971 
972 }
973 
974 void
976  (*theChargedTracks)[nChargedParticleTracks++] = id;
979  theChargedSize *= 2;
981  }
982 }
983 
984 int
986  if (id>=0 && id<(int)nChargedParticleTracks)
987  return (*theChargedTracks)[id];
988  else
989  return -1;
990 }
991 
992 /*
993 const SimTrack &
994 FBaseSimEvent::embdTrack(int i) const {
995  return (*theSimTracks)[i].simTrack();
996 }
997 
998 const SimVertex &
999 FBaseSimEvent::embdVertex(int i) const {
1000  return (*theSimVertices)[i].simVertex();
1001 }
1002 */
1003 
1004 const HepMC::GenParticle*
1006  return (*theGenParticles)[i];
1007 }
1008 
1009 /*
1010 FSimTrack&
1011 FBaseSimEvent::track(int id) const {
1012  return (*theSimTracks)[id];
1013 }
1014 
1015 
1016 FSimVertex&
1017 FBaseSimEvent::vertex(int id) const {
1018  return (*theSimVertices)[id];
1019 }
1020 */
const ParticleDataTable * pdt
double lateVertexPosition
PrimaryVertexGenerator * theVertexGenerator
type
Definition: HCALResponse.h:21
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
const math::XYZVectorD & trackerSurfacePosition() const
Definition: SimTrack.h:36
virtual double energy() const GCC11_FINAL
energy
void setCharge(float q)
set the MEASURED charge
Definition: RawParticle.cc:138
T getParameter(std::string const &) const
int addSimVertex(const XYZTLorentzVector &decayVertex, int im=-1, FSimVertexType::VertexType type=FSimVertexType::ANY)
Add a new vertex to the Event and to the various lists.
int i
Definition: DBlmapReader.cc:9
float charge() const
charge
Definition: FSimTrack.h:47
int addSimTrack(const RawParticle *p, int iv, int ig=-1, const HepMC::GenVertex *ev=0)
Add a new track to the Event and to the various lists.
bool propagateToPreshowerLayer1(bool first=true)
const HepMC::GenParticle * embdGenpart(int i) const
return MC track with a given id
list parent
Definition: dbtoconf.py:74
HepPDT::ParticleDataTable ParticleDataTable
std::vector< FSimTrack > * theSimTracks
virtual int pdgId() const GCC11_FINAL
PDG identifier.
double PDGmass() const
get the THEORETICAL mass
Definition: RawParticle.cc:254
std::vector< unsigned > * theChargedTracks
FBaseSimEvent(const edm::ParameterSet &kine)
Default constructor.
const XYZTLorentzVector & momentum() const
Temporary (until move of SimTrack to Mathcore) - No! Actually very useful.
Definition: FSimTrack.h:190
unsigned int theTrackSize
unsigned int theVertexSize
virtual int status() const =0
status word
KineParticleFilter * myFilter
The particle filter.
math::XYZPoint theBeamSpot
virtual double vx() const =0
x coordinate of vertex position
void setEcal(const RawParticle &pp, int success)
Set the ecal variables.
Definition: FSimTrack.cc:69
int getSuccess() const
Has propagation been performed and was barrel or endcap reached ?
#define abs(x)
Definition: mlp_lapack.h:159
void addParticles(const HepMC::GenEvent &hev)
Add the particles and their vertices to the list.
void setLayer2(const RawParticle &pp, int success)
Set the preshower layer2 variables.
Definition: FSimTrack.cc:62
void clear()
clear the FBaseSimEvent content before the next event
void setMagneticField(double b)
Set the magnetic field.
TRandom random
Definition: MVATrainer.cc:138
unsigned int nSimTracks
T eta() const
virtual double vy() const
y coordinate of vertex position
virtual double pz() const GCC11_FINAL
z coordinate of momentum vector
unsigned int theGenSize
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
float float float z
bool notYetToEndVertex(const XYZTLorentzVector &pos) const
Compare the end vertex position with another position.
Definition: FSimTrack.cc:33
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
virtual double vy() const =0
y coordinate of vertex position
FSimVertex & vertex(int id) const
Return vertex with given Id.
unsigned int nVertices() const
Number of vertices.
FSimVertexType & vertexType(int id) const
Return vertex with given Id.
bool propagateToVFcalEntrance(bool first=true)
void setLayer1(const RawParticle &pp, int success)
Set the preshower layer1 variables.
Definition: FSimTrack.cc:55
const XYZTLorentzVector & momentum() const
the momentum fourvector
Definition: RawParticle.h:285
double t() const
vertex time
Definition: RawParticle.h:272
math::XYZVector XYZVector
int parentIndex() const
Definition: SimVertex.h:33
virtual const_iterator end() const =0
last daughter const_iterator
virtual int status() const GCC11_FINAL
status word
~FBaseSimEvent()
usual virtual destructor
virtual size_t numberOfMothers() const
number of mothers
const math::XYZTLorentzVector & position() const
Temporary (until CMSSW moves to Mathcore) - No ! Actually very useful.
Definition: FSimVertex.h:49
T sqrt(T t)
Definition: SSEVec.h:48
unsigned int nTracks() const
Number of tracks.
Definition: FBaseSimEvent.h:95
bool propagateToHcalExit(bool first=true)
virtual size_t numberOfDaughters() const
number of daughters
unsigned int nSimVertices
int genpartIndex() const
index of the corresponding Generator particle in the Event container (-1 if no Genpart) ...
Definition: SimTrack.h:33
virtual const Candidate * daughter(size_type) const
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
double cos2ThetaV() const
Definition: RawParticle.h:268
A FSimVertexType hold the information on the vertex origine.
#define nParticles
Definition: Histograms.cc:24
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
const math::XYZTLorentzVectorD & position() const
Definition: CoreSimVertex.h:26
std::vector< FSimVertexType > FSimVertexTypeCollection
collection of FSimVertexType objects
const FSimVertex & vertex() const
Origin vertex.
unsigned int nGenParticles
unsigned int initialSize
std::vector< FSimVertex > * theSimVertices
unsigned int offset(bool)
virtual double vz() const
z coordinate of vertex position
bool propagateToEcalEntrance(bool first=true)
int k[5][pyjets_maxn]
void fill(const HepMC::GenEvent &hev)
fill the FBaseSimEvent from the current HepMC::GenEvent
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:29
virtual int pdgId() const =0
PDG identifier.
const XYZTLorentzVector & vertex() const
the vertex fourvector
Definition: RawParticle.h:284
virtual void generate()=0
Generation process (to be implemented)
const RandomEngine * random
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
unsigned int theChargedSize
part
Definition: HCALResponse.h:20
const math::XYZTLorentzVectorD & trackerSurfaceMomentum() const
Definition: SimTrack.h:38
void addChargedTrack(int id)
Add an id in the vector of charged tracks id&#39;s.
void setHcalExit(const RawParticle &pp, int success)
Set the hcal exit variables.
Definition: FSimTrack.cc:90
virtual double vz() const =0
z coordinate of vertex position
unsigned int nChargedParticleTracks
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:40
bool propagateToHcalEntrance(bool first=true)
void initializePdt(const HepPDT::ParticleDataTable *aPdt)
Initialize the particle data table.
void setEndVertex(int endv)
Set the end vertex.
Definition: FSimTrack.h:148
unsigned int nGenParts() const
Number of generator particles.
const math::XYZTLorentzVectorD & momentum() const
particle info...
Definition: CoreSimTrack.h:36
const math::XYZPoint & beamSpot() const
Return x0, y0, z0.
void addDaughter(int i)
Add a RecHit for a track on a layer.
Definition: FSimTrack.h:181
void setHO(const RawParticle &pp, int success)
Set the ho variables.
Definition: FSimTrack.cc:96
int chargedTrack(int id) const
return &quot;reconstructed&quot; charged tracks index.
virtual double vx() const
x coordinate of vertex position
void setVFcal(const RawParticle &pp, int success)
Set the hcal variables.
Definition: FSimTrack.cc:83
tuple cout
Definition: gather_cfg.py:121
void addDaughter(int i)
Definition: FSimVertex.h:46
void setHcal(const RawParticle &pp, int success)
Set the hcal variables.
Definition: FSimTrack.cc:76
bool noParent() const
Definition: SimVertex.h:34
void printMCTruth(const HepMC::GenEvent &hev)
print the original MCTruth event
Definition: DDAxes.h:10
std::vector< HepMC::GenParticle * > * theGenParticles
bool propagateToHOLayer(bool first=true)
bool propagateToPreshowerLayer2(bool first=true)
virtual const Candidate * mother(size_type=0) const
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15
void print() const
print the FBaseSimEvent in an intelligible way
FSimTrack & track(int id) const
Return track with given Id.
FSimVertexTypeCollection * theFSimVerticesType