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  // Loop over the tracks
361  for( int fsimi=0; fsimi < (int)nTracks() ; ++fsimi) {
362 
363 
364  FSimTrack& myTrack = track(fsimi);
365  double trackerSurfaceTime = myTrack.vertex().position().t()
366  + myTrack.momentum().e()/myTrack.momentum().pz()
367  * ( myTrack.trackerSurfacePosition().z()
368  - myTrack.vertex().position().z() );
369  pos = XYZTLorentzVector(myTrack.trackerSurfacePosition().x(),
370  myTrack.trackerSurfacePosition().y(),
371  myTrack.trackerSurfacePosition().z(),
372  trackerSurfaceTime);
373  mom = XYZTLorentzVector(myTrack.trackerSurfaceMomentum().x(),
374  myTrack.trackerSurfaceMomentum().y(),
375  myTrack.trackerSurfaceMomentum().z(),
376  myTrack.trackerSurfaceMomentum().t());
377 
378  if ( mom.T() > 0. ) {
379  // The particle to be propagated
380  myPart = BaseParticlePropagator(RawParticle(mom,pos),0.,0.,4.);
381  myPart.setCharge(myTrack.charge());
382 
383  // Propagate to Preshower layer 1
384  myPart.propagateToPreshowerLayer1(false);
385  if ( myTrack.notYetToEndVertex(myPart.vertex()) && myPart.getSuccess()>0 )
386  myTrack.setLayer1(myPart,myPart.getSuccess());
387 
388  // Propagate to Preshower Layer 2
389  myPart.propagateToPreshowerLayer2(false);
390  if ( myTrack.notYetToEndVertex(myPart.vertex()) && myPart.getSuccess()>0 )
391  myTrack.setLayer2(myPart,myPart.getSuccess());
392 
393  // Propagate to Ecal Endcap
394  myPart.propagateToEcalEntrance(false);
395  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
396  myTrack.setEcal(myPart,myPart.getSuccess());
397 
398  // Propagate to HCAL entrance
399  myPart.propagateToHcalEntrance(false);
400  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
401  myTrack.setHcal(myPart,myPart.getSuccess());
402 
403  // Propagate to VFCAL entrance
404  myPart.propagateToVFcalEntrance(false);
405  if ( myTrack.notYetToEndVertex(myPart.vertex()) )
406  myTrack.setVFcal(myPart,myPart.getSuccess());
407  }
408 
409  }
410 
411 }
412 
413 
414 void
415 FBaseSimEvent::addParticles(const HepMC::GenEvent& myGenEvent) {
416 
418  int genEventSize = myGenEvent.particles_size();
419  std::vector<int> myGenVertices(genEventSize, static_cast<int>(0));
420 
421  // If no particles, no work to be done !
422  if ( myGenEvent.particles_empty() ) return;
423 
424  // Are there particles in the FSimEvent already ?
425  int offset = nGenParts();
426 
427  // Primary vertex (already smeared by the SmearedVtx module)
428  HepMC::GenVertex* primaryVertex = *(myGenEvent.vertices_begin());
429 
430  // Beginning of workaround a bug in pythia particle gun
431  unsigned primaryMother = primaryVertex->particles_in_size();
432  if ( primaryMother ) {
433  unsigned partId = (*(primaryVertex->particles_in_const_begin()))->pdg_id();
434  if ( abs(partId) == 2212 ) primaryMother = 0;
435  }
436  // End of workaround a bug in pythia particle gun
437 
438  XYZTLorentzVector primaryVertexPosition(primaryVertex->position().x()/10.,
439  primaryVertex->position().y()/10.,
440  primaryVertex->position().z()/10.,
441  primaryVertex->position().t()/10.);
442  // Actually this is the true end of the workaround
443  primaryVertexPosition *= (1-primaryMother);
444  // THE END.
445 
446  // Smear the main vertex if needed
447  // Now takes the origin from the database
448  XYZTLorentzVector smearedVertex;
449  if ( primaryVertexPosition.Vect().Mag2() < 1E-16 ) {
451  smearedVertex = XYZTLorentzVector(
455  0.);
456  }
457 
458  // Set the main vertex
459  myFilter->setMainVertex(primaryVertexPosition+smearedVertex);
460 
461  // This is the smeared main vertex
462  int mainVertex = addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
463 
464  HepMC::GenEvent::particle_const_iterator piter;
465  HepMC::GenEvent::particle_const_iterator pbegin = myGenEvent.particles_begin();
466  HepMC::GenEvent::particle_const_iterator pend = myGenEvent.particles_end();
467 
468  int initialBarcode = 0;
469  if ( pbegin != pend ) initialBarcode = (*pbegin)->barcode();
470  // Loop on the particles of the generated event
471  for ( piter = pbegin; piter != pend; ++piter ) {
472 
473  // This is the generated particle pointer - for the signal event only
474  HepMC::GenParticle* p = *piter;
475 
476  if ( !offset ) {
477  (*theGenParticles)[nGenParticles++] = p;
479  theGenSize *= 2;
480  theGenParticles->resize(theGenSize);
481  }
482 
483  }
484 
485  // Reject particles with late origin vertex (i.e., coming from late decays)
486  // This should not happen, but one never knows what users may be up to!
487  // For example exotic particles might decay late - keep the decay products in the case.
488  XYZTLorentzVector productionVertexPosition(0.,0.,0.,0.);
489  HepMC::GenVertex* productionVertex = p->production_vertex();
490  if ( productionVertex ) {
491  unsigned productionMother = productionVertex->particles_in_size();
492  if ( productionMother ) {
493  unsigned motherId = (*(productionVertex->particles_in_const_begin()))->pdg_id();
494  if ( abs(motherId) < 1000000 )
495  productionVertexPosition =
496  XYZTLorentzVector(productionVertex->position().x()/10.,
497  productionVertex->position().y()/10.,
498  productionVertex->position().z()/10.,
499  productionVertex->position().t()/10.) + smearedVertex;
500  }
501  }
502  if ( !myFilter->accept(productionVertexPosition) ) continue;
503 
504  int abspdgId = abs(p->pdg_id());
505  HepMC::GenVertex* endVertex = p->end_vertex();
506 
507  // Keep only:
508  // 1) Stable particles (watch out! New status code = 1001!)
509  bool testStable = p->status()%1000==1;
510  // Declare stable standard particles that decay after a macroscopic path length
511  // (except if exotic)
512  if ( p->status() == 2 && abspdgId < 1000000) {
513  if ( endVertex ) {
514  XYZTLorentzVector decayPosition =
515  XYZTLorentzVector(endVertex->position().x()/10.,
516  endVertex->position().y()/10.,
517  endVertex->position().z()/10.,
518  endVertex->position().t()/10.) + smearedVertex;
519  // If the particle flew enough to be beyond the beam pipe enveloppe, just declare it stable
520  if ( decayPosition.Perp2() > lateVertexPosition ) testStable = true;
521  }
522  }
523 
524  // 2) or particles with stable daughters (watch out! New status code = 1001!)
525  bool testDaugh = false;
526  if ( !testStable &&
527  p->status() == 2 &&
528  endVertex &&
529  endVertex->particles_out_size() ) {
530  HepMC::GenVertex::particles_out_const_iterator firstDaughterIt =
531  endVertex->particles_out_const_begin();
532  HepMC::GenVertex::particles_out_const_iterator lastDaughterIt =
533  endVertex->particles_out_const_end();
534  for ( ; firstDaughterIt != lastDaughterIt ; ++firstDaughterIt ) {
535  HepMC::GenParticle* daugh = *firstDaughterIt;
536  if ( daugh->status()%1000==1 ) {
537  // Check that it is not a "prompt electron or muon brem":
538  if (abspdgId == 11 || abspdgId == 13) {
539  if ( endVertex ) {
540  XYZTLorentzVector endVertexPosition = XYZTLorentzVector(endVertex->position().x()/10.,
541  endVertex->position().y()/10.,
542  endVertex->position().z()/10.,
543  endVertex->position().t()/10.);
544  // If the particle flew enough to be beyond the beam pipe enveloppe, just declare it stable
545  if ( endVertexPosition.Perp2() < lateVertexPosition ) {
546  break;
547  }
548  }
549  }
550  testDaugh=true;
551  break;
552  }
553  }
554  }
555 
556  // 3) or particles that fly more than one micron.
557  double dist = 0.;
558  if ( !testStable && !testDaugh && p->production_vertex() ) {
560  productionVertexPosition(p->production_vertex()->position().x()/10.,
561  p->production_vertex()->position().y()/10.,
562  p->production_vertex()->position().z()/10.,
563  p->production_vertex()->position().t()/10.);
564  dist = (primaryVertexPosition-productionVertexPosition).Vect().Mag2();
565  }
566  bool testDecay = ( dist > 1e-8 ) ? true : false;
567 
568  // Save the corresponding particle and vertices
569  if ( testStable || testDaugh || testDecay ) {
570 
571  /*
572  const HepMC::GenParticle* mother = p->production_vertex() ?
573  *(p->production_vertex()->particles_in_const_begin()) : 0;
574  */
575 
576  int motherBarcode = p->production_vertex() &&
577  p->production_vertex()->particles_in_const_begin() !=
578  p->production_vertex()->particles_in_const_end() ?
579  (*(p->production_vertex()->particles_in_const_begin()))->barcode() : 0;
580 
581  int originVertex =
582  motherBarcode && myGenVertices[motherBarcode-initialBarcode] ?
583  myGenVertices[motherBarcode-initialBarcode] : mainVertex;
584 
585  XYZTLorentzVector momentum(p->momentum().px(),
586  p->momentum().py(),
587  p->momentum().pz(),
588  p->momentum().e());
589  RawParticle part(momentum, vertex(originVertex).position());
590  part.setID(p->pdg_id());
591 
592  // Add the particle to the event and to the various lists
593 
594  int theTrack = testStable && p->end_vertex() ?
595  // The particle is scheduled to decay
596  addSimTrack(&part,originVertex, nGenParts()-offset,p->end_vertex()) :
597  // The particle is not scheduled to decay
598  addSimTrack(&part,originVertex, nGenParts()-offset);
599 
600  if (
601  // This one deals with particles with no end vertex
602  !p->end_vertex() ||
603  // This one deals with particles that have a pre-defined
604  // decay proper time, but have not decayed yet
605  ( testStable && p->end_vertex() && !p->end_vertex()->particles_out_size() )
606  // In both case, just don't add a end vertex in the FSimEvent
607  ) continue;
608 
609  // Add the vertex to the event and to the various lists
610  XYZTLorentzVector decayVertex =
611  XYZTLorentzVector(p->end_vertex()->position().x()/10.,
612  p->end_vertex()->position().y()/10.,
613  p->end_vertex()->position().z()/10.,
614  p->end_vertex()->position().t()/10.) +
615  smearedVertex;
616  // vertex(mainVertex).position();
617  int theVertex = addSimVertex(decayVertex,theTrack, FSimVertexType::DECAY_VERTEX);
618 
619  if ( theVertex != -1 ) myGenVertices[p->barcode()-initialBarcode] = theVertex;
620 
621  // There we are !
622  }
623  }
624 
625 }
626 
627 void
629 
630  // If no particles, no work to be done !
631  unsigned int nParticles = myGenParticles.size();
633 
634  if ( !nParticles ) return;
635 
637  std::map<const reco::Candidate*,int> myGenVertices;
638 
639  // Are there particles in the FSimEvent already ?
640  int offset = nTracks();
641 
642  // Skip the incoming protons
643  nGenParticles = 0;
644  unsigned int ip = 0;
645  if ( nParticles > 1 &&
646  myGenParticles[0].pdgId() == 2212 &&
647  myGenParticles[1].pdgId() == 2212 ) {
648  ip = 2;
649  nGenParticles = 2;
650  }
651 
652  // Primary vertex (already smeared by the SmearedVtx module)
653  XYZTLorentzVector primaryVertex (myGenParticles[ip].vx(),
654  myGenParticles[ip].vy(),
655  myGenParticles[ip].vz(),
656  0.);
657 
658  // Smear the main vertex if needed
659  XYZTLorentzVector smearedVertex;
660  if ( primaryVertex.mag() < 1E-8 ) {
662  smearedVertex = XYZTLorentzVector(
666  0.);
667  }
668 
669  // Set the main vertex
670  myFilter->setMainVertex(primaryVertex+smearedVertex);
671 
672  // This is the smeared main vertex
673  int mainVertex = addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
674 
675  // Loop on the particles of the generated event
676  for ( ; ip<nParticles; ++ip ) {
677 
678  // nGenParticles = ip;
679 
680  nGenParticles++;
681  const reco::GenParticle& p = myGenParticles[ip];
682 
683  // Reject particles with late origin vertex (i.e., coming from late decays)
684  // This should not happen, but one never knows what users may be up to!
685  // For example exotic particles might decay late - keep the decay products in the case.
686  XYZTLorentzVector productionVertexPosition(0.,0.,0.,0.);
687  const reco::Candidate* productionMother = p.numberOfMothers() ? p.mother(0) : 0;
688  if ( productionMother ) {
689  unsigned motherId = productionMother->pdgId();
690  if ( abs(motherId) < 1000000 )
691  productionVertexPosition = XYZTLorentzVector(p.vx(), p.vy(), p.vz(), 0.) + smearedVertex;
692  }
693  if ( !myFilter->accept(productionVertexPosition) ) continue;
694 
695  // Keep only:
696  // 1) Stable particles
697  bool testStable = p.status()%1000==1;
698  // Declare stable standard particles that decay after a macroscopic path length
699  // (except if exotic particle)
700  if ( p.status() == 2 && abs(p.pdgId()) < 1000000 ) {
701  unsigned int nDaughters = p.numberOfDaughters();
702  if ( nDaughters ) {
703  const reco::Candidate* daughter = p.daughter(0);
704  XYZTLorentzVector decayPosition =
705  XYZTLorentzVector(daughter->vx(), daughter->vy(), daughter->vz(), 0.) + smearedVertex;
706  // If the particle flew enough to be beyond the beam pipe enveloppe, just declare it stable
707  if ( decayPosition.Perp2() > lateVertexPosition ) testStable = true;
708  }
709  }
710 
711  // 2) or particles with stable daughters
712  bool testDaugh = false;
713  unsigned int nDaughters = p.numberOfDaughters();
714  if ( !testStable &&
715  // p.status() == 2 &&
716  nDaughters ) {
717  for ( unsigned iDaughter=0; iDaughter<nDaughters; ++iDaughter ) {
718  const reco::Candidate* daughter = p.daughter(iDaughter);
719  if ( daughter->status()%1000==1 ) {
720  testDaugh=true;
721  break;
722  }
723  }
724  }
725 
726  // 3) or particles that fly more than one micron.
727  double dist = 0.;
728  if ( !testStable && !testDaugh ) {
729  XYZTLorentzVector productionVertex(p.vx(),p.vy(),p.vz(),0.);
730  dist = (primaryVertex-productionVertex).Vect().Mag2();
731  }
732  bool testDecay = ( dist > 1e-8 ) ? true : false;
733 
734  // Save the corresponding particle and vertices
735  if ( testStable || testDaugh || testDecay ) {
736 
737  const reco::Candidate* mother = p.numberOfMothers() ? p.mother(0) : 0;
738 
739  int originVertex =
740  mother &&
741  myGenVertices.find(mother) != myGenVertices.end() ?
742  myGenVertices[mother] : mainVertex;
743 
744  XYZTLorentzVector momentum(p.px(),p.py(),p.pz(),p.energy());
745  RawParticle part(momentum, vertex(originVertex).position());
746  part.setID(p.pdgId());
747 
748  // Add the particle to the event and to the various lists
749  int theTrack = addSimTrack(&part,originVertex, nGenParts()-offset);
750 
751  // It there an end vertex ?
752  if ( !nDaughters ) continue;
753  const reco::Candidate* daughter = p.daughter(0);
754 
755  // Add the vertex to the event and to the various lists
756  XYZTLorentzVector decayVertex =
757  XYZTLorentzVector(daughter->vx(), daughter->vy(),
758  daughter->vz(), 0.) + smearedVertex;
759  int theVertex = addSimVertex(decayVertex,theTrack, FSimVertexType::DECAY_VERTEX);
760 
761  if ( theVertex != -1 ) myGenVertices[&p] = theVertex;
762 
763  // There we are !
764  }
765  }
766 
767  // There is no GenParticle's in that case...
768  // nGenParticles=0;
769 
770 }
771 
772 int
773 FBaseSimEvent::addSimTrack(const RawParticle* p, int iv, int ig,
774  const HepMC::GenVertex* ev) {
775 
776  // Check that the particle is in the Famos "acceptance"
777  // Keep all primaries of pile-up events, though
778  if ( !myFilter->accept(p) && ig >= -1 ) return -1;
779 
780  // The new track index
781  int trackId = nSimTracks++;
783  theTrackSize *= 2;
784  theSimTracks->resize(theTrackSize);
785  }
786 
787  // Attach the particle to the origin vertex, and to the mother
788  vertex(iv).addDaughter(trackId);
789  if ( !vertex(iv).noParent() ) {
790  track(vertex(iv).parent().id()).addDaughter(trackId);
791 
792  if ( ig == -1 ) {
793  int motherId = track(vertex(iv).parent().id()).genpartIndex();
794  if ( motherId < -1 ) ig = motherId;
795  }
796  }
797 
798  // Some transient information for FAMOS internal use
799  (*theSimTracks)[trackId] = ev ?
800  // A proper decay time is scheduled
801  FSimTrack(p,iv,ig,trackId,this,
802  ev->position().t()/10.
803  * p->PDGmass()
804  / std::sqrt(p->momentum().Vect().Mag2())) :
805  // No proper decay time is scheduled
806  FSimTrack(p,iv,ig,trackId,this);
807 
808  return trackId;
809 
810 }
811 
812 int
814 
815  // Check that the vertex is in the Famos "acceptance"
816  if ( !myFilter->accept(v) ) return -1;
817 
818  // The number of vertices
819  int vertexId = nSimVertices++;
821  theVertexSize *= 2;
822  theSimVertices->resize(theVertexSize);
824  }
825 
826  // Attach the end vertex to the particle (if accepted)
827  if ( im !=-1 ) track(im).setEndVertex(vertexId);
828 
829  // Some transient information for FAMOS internal use
830  (*theSimVertices)[vertexId] = FSimVertex(v,im,vertexId,this);
831 
832  (*theFSimVerticesType)[vertexId] = FSimVertexType(type);
833 
834  return vertexId;
835 
836 }
837 
838 void
839 FBaseSimEvent::printMCTruth(const HepMC::GenEvent& myGenEvent) {
840 
841  std::cout << "Id Gen Name eta phi pT E Vtx1 "
842  << " x y z "
843  << "Moth Vtx2 eta phi R Z Da1 Da2 Ecal?" << std::endl;
844 
845  for ( HepMC::GenEvent::particle_const_iterator
846  piter = myGenEvent.particles_begin();
847  piter != myGenEvent.particles_end();
848  ++piter ) {
849 
850  HepMC::GenParticle* p = *piter;
851  /* */
852  int partId = p->pdg_id();
853  std::string name;
854 
855  if ( pdt->particle(ParticleID(partId)) !=0 ) {
856  name = (pdt->particle(ParticleID(partId)))->name();
857  } else {
858  name = "none";
859  }
860 
861  XYZTLorentzVector momentum1(p->momentum().px(),
862  p->momentum().py(),
863  p->momentum().pz(),
864  p->momentum().e());
865 
866  int vertexId1 = 0;
867 
868  if ( !p->production_vertex() ) continue;
869 
870  XYZVector vertex1 (p->production_vertex()->position().x()/10.,
871  p->production_vertex()->position().y()/10.,
872  p->production_vertex()->position().z()/10.);
873  vertexId1 = p->production_vertex()->barcode();
874 
875  std::cout.setf(std::ios::fixed, std::ios::floatfield);
876  std::cout.setf(std::ios::right, std::ios::adjustfield);
877 
878  std::cout << std::setw(4) << p->barcode() << " "
879  << name;
880 
881  for(unsigned int k=0;k<11-name.length() && k<12; k++) std::cout << " ";
882 
883  double eta = momentum1.eta();
884  if ( eta > +10. ) eta = +10.;
885  if ( eta < -10. ) eta = -10.;
886  std::cout << std::setw(6) << std::setprecision(2) << eta << " "
887  << std::setw(6) << std::setprecision(2) << momentum1.phi() << " "
888  << std::setw(7) << std::setprecision(2) << momentum1.pt() << " "
889  << std::setw(7) << std::setprecision(2) << momentum1.e() << " "
890  << std::setw(4) << vertexId1 << " "
891  << std::setw(6) << std::setprecision(1) << vertex1.x() << " "
892  << std::setw(6) << std::setprecision(1) << vertex1.y() << " "
893  << std::setw(6) << std::setprecision(1) << vertex1.z() << " ";
894 
895  const HepMC::GenParticle* mother =
896  *(p->production_vertex()->particles_in_const_begin());
897 
898  if ( mother )
899  std::cout << std::setw(4) << mother->barcode() << " ";
900  else
901  std::cout << " " ;
902 
903  if ( p->end_vertex() ) {
904  XYZTLorentzVector vertex2(p->end_vertex()->position().x()/10.,
905  p->end_vertex()->position().y()/10.,
906  p->end_vertex()->position().z()/10.,
907  p->end_vertex()->position().t()/10.);
908  int vertexId2 = p->end_vertex()->barcode();
909 
910  std::vector<const HepMC::GenParticle*> children;
911  HepMC::GenVertex::particles_out_const_iterator firstDaughterIt =
912  p->end_vertex()->particles_out_const_begin();
913  HepMC::GenVertex::particles_out_const_iterator lastDaughterIt =
914  p->end_vertex()->particles_out_const_end();
915  for ( ; firstDaughterIt != lastDaughterIt ; ++firstDaughterIt ) {
916  children.push_back(*firstDaughterIt);
917  }
918 
919  std::cout << std::setw(4) << vertexId2 << " "
920  << std::setw(6) << std::setprecision(2) << vertex2.eta() << " "
921  << std::setw(6) << std::setprecision(2) << vertex2.phi() << " "
922  << std::setw(5) << std::setprecision(1) << vertex2.pt() << " "
923  << std::setw(6) << std::setprecision(1) << vertex2.z() << " ";
924  for ( unsigned id=0; id<children.size(); ++id )
925  std::cout << std::setw(4) << children[id]->barcode() << " ";
926  }
927  std::cout << std::endl;
928 
929  }
930 
931 }
932 
933 void
935 
936  std::cout << " Id Gen Name eta phi pT E Vtx1 "
937  << " x y z "
938  << "Moth Vtx2 eta phi R Z Daughters Ecal?" << std::endl;
939 
940  for( int i=0; i<(int)nTracks(); i++ )
941  std::cout << track(i) << std::endl;
942 
943  for( int i=0; i<(int)nVertices(); i++ )
944  std::cout << "i = " << i << " " << vertexType(i) << std::endl;
945 
946 
947 
948 }
949 
950 void
952 
953  nSimTracks = 0;
954  nSimVertices = 0;
955  nGenParticles = 0;
957 
958 }
959 
960 void
962  (*theChargedTracks)[nChargedParticleTracks++] = id;
965  theChargedSize *= 2;
967  }
968 }
969 
970 int
972  if (id>=0 && id<(int)nChargedParticleTracks)
973  return (*theChargedTracks)[id];
974  else
975  return -1;
976 }
977 
978 /*
979 const SimTrack &
980 FBaseSimEvent::embdTrack(int i) const {
981  return (*theSimTracks)[i].simTrack();
982 }
983 
984 const SimVertex &
985 FBaseSimEvent::embdVertex(int i) const {
986  return (*theSimVertices)[i].simVertex();
987 }
988 */
989 
990 const HepMC::GenParticle*
992  return (*theGenParticles)[i];
993 }
994 
995 /*
996 FSimTrack&
997 FBaseSimEvent::track(int id) const {
998  return (*theSimTracks)[id];
999 }
1000 
1001 
1002 FSimVertex&
1003 FBaseSimEvent::vertex(int id) const {
1004  return (*theSimVertices)[id];
1005 }
1006 */
const ParticleDataTable * pdt
double lateVertexPosition
PrimaryVertexGenerator * theVertexGenerator
type
Definition: HCALResponse.h:22
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
const math::XYZVectorD & trackerSurfacePosition() const
Definition: SimTrack.h:36
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
virtual int pdgId() const
PDG identifier.
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 status() const
status word
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:168
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
TRandom random
Definition: MVATrainer.cc:138
unsigned int nSimTracks
T eta() const
virtual double vy() const
y coordinate of vertex position
unsigned int theGenSize
double double double 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)
virtual double energy() const
energy
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
~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:28
unsigned int nTracks() const
Number of tracks.
Definition: FBaseSimEvent.h:95
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) ...
A FSimVertexType hold the information on the vertex origine.
#define nParticles
Definition: Histograms.cc:25
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
virtual double px() const
x coordinate of momentum vector
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
unsigned int theChargedSize
part
Definition: HCALResponse.h:21
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.
virtual double pz() const
z coordinate of momentum vector
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:132
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:159
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:41
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 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) ...
mathSSE::Vec4< T > v
virtual double py() const
y coordinate of momentum vector
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