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