00001
00002 #include "HepMC/GenEvent.h"
00003 #include "HepMC/GenVertex.h"
00004 #include "HepMC/GenParticle.h"
00005
00006
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008
00009
00010 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00011 #include "DataFormats/Candidate/interface/Candidate.h"
00012
00013
00014 #include "FastSimulation/Event/interface/FBaseSimEvent.h"
00015 #include "FastSimulation/Event/interface/FSimTrack.h"
00016 #include "FastSimulation/Event/interface/FSimVertex.h"
00017 #include "FastSimulation/Event/interface/KineParticleFilter.h"
00018 #include "FastSimulation/BaseParticlePropagator/interface/BaseParticlePropagator.h"
00019 #include "FastSimulation/Event/interface/BetaFuncPrimaryVertexGenerator.h"
00020 #include "FastSimulation/Event/interface/GaussianPrimaryVertexGenerator.h"
00021 #include "FastSimulation/Event/interface/FlatPrimaryVertexGenerator.h"
00022 #include "FastSimulation/Event/interface/NoPrimaryVertexGenerator.h"
00023
00024 #include "FastSimDataFormats/NuclearInteractions/interface/FSimVertexType.h"
00025
00026 using namespace HepPDT;
00027
00028
00029 #include <iostream>
00030 #include <iomanip>
00031 #include <map>
00032 #include <string>
00033
00034 FBaseSimEvent::FBaseSimEvent(const edm::ParameterSet& kine)
00035 :
00036 nSimTracks(0),
00037 nSimVertices(0),
00038 nGenParticles(0),
00039 nChargedParticleTracks(0),
00040 initialSize(5000),
00041 random(0)
00042 {
00043
00044 theVertexGenerator = new NoPrimaryVertexGenerator();
00045 theBeamSpot = math::XYZPoint(0.0,0.0,0.0);
00046
00047
00048 theGenParticles = new std::vector<HepMC::GenParticle*>();
00049 theSimTracks = new std::vector<FSimTrack>;
00050 theSimVertices = new std::vector<FSimVertex>;
00051 theChargedTracks = new std::vector<unsigned>();
00052 theFSimVerticesType = new FSimVertexTypeCollection();
00053
00054
00055
00056 theSimTracks->resize(initialSize);
00057 theSimVertices->resize(initialSize);
00058 theGenParticles->resize(initialSize);
00059 theChargedTracks->resize(initialSize);
00060 theFSimVerticesType->resize(initialSize);
00061 theTrackSize = initialSize;
00062 theVertexSize = initialSize;
00063 theGenSize = initialSize;
00064 theChargedSize = initialSize;
00065
00066
00067
00068 myFilter = new KineParticleFilter(kine);
00069
00070 }
00071
00072 FBaseSimEvent::FBaseSimEvent(const edm::ParameterSet& vtx,
00073 const edm::ParameterSet& kine,
00074 const RandomEngine* engine)
00075 :
00076 nSimTracks(0),
00077 nSimVertices(0),
00078 nGenParticles(0),
00079 nChargedParticleTracks(0),
00080 initialSize(5000),
00081 theVertexGenerator(0),
00082 random(engine)
00083 {
00084
00085
00086 std::string vtxType = vtx.getParameter<std::string>("type");
00087 if ( vtxType == "Gaussian" )
00088 theVertexGenerator = new GaussianPrimaryVertexGenerator(vtx,random);
00089 else if ( vtxType == "Flat" )
00090 theVertexGenerator = new FlatPrimaryVertexGenerator(vtx,random);
00091 else if ( vtxType == "BetaFunc" )
00092 theVertexGenerator = new BetaFuncPrimaryVertexGenerator(vtx,random);
00093 else
00094 theVertexGenerator = new NoPrimaryVertexGenerator();
00095
00096 theBeamSpot = math::XYZPoint(0.0,0.0,0.0);
00097
00098
00099
00100
00101 lateVertexPosition = 2.5*2.5;
00102
00103
00104 theGenParticles = new std::vector<HepMC::GenParticle*>();
00105 theSimTracks = new std::vector<FSimTrack>;
00106 theSimVertices = new std::vector<FSimVertex>;
00107 theChargedTracks = new std::vector<unsigned>();
00108 theFSimVerticesType = new FSimVertexTypeCollection();
00109
00110
00111
00112 theSimTracks->resize(initialSize);
00113 theSimVertices->resize(initialSize);
00114 theGenParticles->resize(initialSize);
00115 theChargedTracks->resize(initialSize);
00116 theFSimVerticesType->resize(initialSize);
00117 theTrackSize = initialSize;
00118 theVertexSize = initialSize;
00119 theGenSize = initialSize;
00120 theChargedSize = initialSize;
00121
00122
00123
00124 myFilter = new KineParticleFilter(kine);
00125
00126 }
00127
00128 FBaseSimEvent::~FBaseSimEvent(){
00129
00130
00131 theGenParticles->clear();
00132 theSimTracks->clear();
00133 theSimVertices->clear();
00134 theChargedTracks->clear();
00135 theFSimVerticesType->clear();
00136
00137
00138 delete theGenParticles;
00139 delete theSimTracks;
00140 delete theSimVertices;
00141 delete theChargedTracks;
00142 delete theFSimVerticesType;
00143 delete myFilter;
00144
00145 }
00146
00147 void
00148 FBaseSimEvent::initializePdt(const HepPDT::ParticleDataTable* aPdt) {
00149
00150 pdt = aPdt;
00151
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 void
00162 FBaseSimEvent::fill(const HepMC::GenEvent& myGenEvent) {
00163
00164
00165 clear();
00166
00167
00168 addParticles(myGenEvent);
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 }
00179
00180 void
00181 FBaseSimEvent::fill(const reco::GenParticleCollection& myGenParticles) {
00182
00183
00184 clear();
00185
00186
00187 addParticles(myGenParticles);
00188
00189 }
00190
00191 void
00192 FBaseSimEvent::fill(const std::vector<SimTrack>& simTracks,
00193 const std::vector<SimVertex>& simVertices) {
00194
00195
00196
00197
00198 clear();
00199
00200 unsigned nVtx = simVertices.size();
00201 unsigned nTks = simTracks.size();
00202
00203
00204 if ( nVtx == 0 ) return;
00205
00206
00207 std::vector<int> myVertices(nVtx,-1);
00208 std::vector<int> myTracks(nTks,-1);
00209
00210
00211
00212
00213 std::map<unsigned, unsigned> geantToIndex;
00214 for( unsigned it=0; it<simTracks.size(); ++it ) {
00215 geantToIndex[ simTracks[it].trackId() ] = it;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 XYZTLorentzVector primaryVertex(simVertices[0].position().x(),
00234 simVertices[0].position().y(),
00235 simVertices[0].position().z(),
00236 simVertices[0].position().t());
00237
00238 myFilter->setMainVertex(primaryVertex);
00239
00240 addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
00241 myVertices[0] = 0;
00242
00243 for( unsigned trackId=0; trackId<nTks; ++trackId ) {
00244
00245
00246 const SimTrack& track = simTracks[trackId];
00247
00248
00249
00250 int vertexId = track.vertIndex();
00251 const SimVertex& vertex = simVertices[vertexId];
00252
00253
00254
00255 int motherId = -1;
00256 if( !vertex.noParent() ) {
00257
00258 unsigned motherGeantId = vertex.parentIndex();
00259 std::map<unsigned, unsigned >::iterator association
00260 = geantToIndex.find( motherGeantId );
00261 if(association != geantToIndex.end() )
00262 motherId = association->second;
00263 }
00264 int originId = motherId == - 1 ? -1 : myTracks[motherId];
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 XYZTLorentzVector position(vertex.position().px(),vertex.position().py(),
00277 vertex.position().pz(),vertex.position().e());
00278 if ( myVertices[vertexId] == -1 )
00279
00280
00281
00282
00283 myVertices[vertexId] = addSimVertex(position,originId);
00284
00285
00286 int motherType = motherId == -1 ? 0 : simTracks[motherId].type();
00287
00288 bool notBremInDetector =
00289 (abs(motherType) != 11 && abs(motherType) != 13) ||
00290 motherType != track.type() ||
00291 position.Perp2() < lateVertexPosition ;
00292
00293 if ( notBremInDetector ) {
00294
00295
00296
00297
00298 XYZTLorentzVector momentum(track.momentum().px(),track.momentum().py(),
00299 track.momentum().pz(),track.momentum().e());
00300 RawParticle part(momentum,position);
00301
00302 part.setID(track.type());
00303
00304
00305
00306
00307 myTracks[trackId] = addSimTrack(&part,myVertices[vertexId],track.genpartIndex());
00308 if ( myTracks[trackId] >= 0 ) {
00309 (*theSimTracks)[ myTracks[trackId] ].setTkPosition(track.trackerSurfacePosition());
00310 (*theSimTracks)[ myTracks[trackId] ].setTkMomentum(track.trackerSurfaceMomentum());
00311 }
00312 } else {
00313
00314 myTracks[trackId] = myTracks[motherId];
00315 if ( myTracks[trackId] >= 0 ) {
00316 (*theSimTracks)[ myTracks[trackId] ].setTkPosition(track.trackerSurfacePosition());
00317 (*theSimTracks)[ myTracks[trackId] ].setTkMomentum(track.trackerSurfaceMomentum());
00318 }
00319 }
00320
00321 }
00322
00323
00324 for( unsigned vertexId=0; vertexId<nVtx; ++vertexId ) {
00325
00326
00327 if ( myVertices[vertexId] != -1 ) continue;
00328
00329
00330 const SimVertex& vertex = simVertices[vertexId];
00331
00332
00333 int motherId = -1;
00334 if( !vertex.noParent() ) {
00335
00336
00337 unsigned motherGeantId = vertex.parentIndex();
00338 std::map<unsigned, unsigned >::iterator association
00339 = geantToIndex.find( motherGeantId );
00340 if(association != geantToIndex.end() )
00341 motherId = association->second;
00342 }
00343 int originId = motherId == - 1 ? -1 : myTracks[motherId];
00344
00345
00346
00347
00348
00349
00350 XYZTLorentzVector position(vertex.position().px(),vertex.position().py(),
00351 vertex.position().pz(),vertex.position().e());
00352 myVertices[vertexId] = addSimVertex(position,originId);
00353 }
00354
00355
00356 BaseParticlePropagator myPart;
00357 XYZTLorentzVector mom;
00358 XYZTLorentzVector pos;
00359
00360
00361
00362 for( int fsimi=0; fsimi < (int)nTracks() ; ++fsimi) {
00363
00364
00365 FSimTrack& myTrack = track(fsimi);
00366 double trackerSurfaceTime = myTrack.vertex().position().t()
00367 + myTrack.momentum().e()/myTrack.momentum().pz()
00368 * ( myTrack.trackerSurfacePosition().z()
00369 - myTrack.vertex().position().z() );
00370 pos = XYZTLorentzVector(myTrack.trackerSurfacePosition().x(),
00371 myTrack.trackerSurfacePosition().y(),
00372 myTrack.trackerSurfacePosition().z(),
00373 trackerSurfaceTime);
00374 mom = XYZTLorentzVector(myTrack.trackerSurfaceMomentum().x(),
00375 myTrack.trackerSurfaceMomentum().y(),
00376 myTrack.trackerSurfaceMomentum().z(),
00377 myTrack.trackerSurfaceMomentum().t());
00378
00379 if ( mom.T() > 0. ) {
00380
00381 myPart = BaseParticlePropagator(RawParticle(mom,pos),0.,0.,4.);
00382 myPart.setCharge(myTrack.charge());
00383
00384
00385 myPart.propagateToPreshowerLayer1(false);
00386 if ( myTrack.notYetToEndVertex(myPart.vertex()) && myPart.getSuccess()>0 )
00387 myTrack.setLayer1(myPart,myPart.getSuccess());
00388
00389
00390 myPart.propagateToPreshowerLayer2(false);
00391 if ( myTrack.notYetToEndVertex(myPart.vertex()) && myPart.getSuccess()>0 )
00392 myTrack.setLayer2(myPart,myPart.getSuccess());
00393
00394
00395 myPart.propagateToEcalEntrance(false);
00396 if ( myTrack.notYetToEndVertex(myPart.vertex()) )
00397 myTrack.setEcal(myPart,myPart.getSuccess());
00398
00399
00400 myPart.propagateToHcalEntrance(false);
00401 if ( myTrack.notYetToEndVertex(myPart.vertex()) )
00402 myTrack.setHcal(myPart,myPart.getSuccess());
00403
00404
00405 if ( myPart.cos2ThetaV()>0.8 || mom.T() < 3. ) {
00406
00407 myPart.propagateToVFcalEntrance(false);
00408 if ( myTrack.notYetToEndVertex(myPart.vertex()) )
00409 myTrack.setVFcal(myPart,myPart.getSuccess());
00410
00411
00412 } else {
00413
00414 myPart.propagateToHcalExit(false);
00415 if ( myTrack.notYetToEndVertex(myPart.vertex()) )
00416 myTrack.setHcalExit(myPart,myPart.getSuccess());
00417
00418 myPart.setMagneticField(0);
00419 myPart.propagateToHOLayer(false);
00420 if ( myTrack.notYetToEndVertex(myPart.vertex()) )
00421 myTrack.setHO(myPart,myPart.getSuccess());
00422 }
00423 }
00424 }
00425 }
00426
00427
00428 void
00429 FBaseSimEvent::addParticles(const HepMC::GenEvent& myGenEvent) {
00430
00432 int genEventSize = myGenEvent.particles_size();
00433 std::vector<int> myGenVertices(genEventSize, static_cast<int>(0));
00434
00435
00436 if ( myGenEvent.particles_empty() ) return;
00437
00438
00439 int offset = nGenParts();
00440
00441
00442 HepMC::GenVertex* primaryVertex = *(myGenEvent.vertices_begin());
00443
00444
00445 unsigned primaryMother = primaryVertex->particles_in_size();
00446 if ( primaryMother ) {
00447 unsigned partId = (*(primaryVertex->particles_in_const_begin()))->pdg_id();
00448 if ( abs(partId) == 2212 ) primaryMother = 0;
00449 }
00450
00451
00452 XYZTLorentzVector primaryVertexPosition(primaryVertex->position().x()/10.,
00453 primaryVertex->position().y()/10.,
00454 primaryVertex->position().z()/10.,
00455 primaryVertex->position().t()/10.);
00456
00457 primaryVertexPosition *= (1-primaryMother);
00458
00459
00460
00461
00462 XYZTLorentzVector smearedVertex;
00463 if ( primaryVertexPosition.Vect().Mag2() < 1E-16 ) {
00464 theVertexGenerator->generate();
00465 smearedVertex = XYZTLorentzVector(
00466 theVertexGenerator->X()-theVertexGenerator->beamSpot().X()+theBeamSpot.X(),
00467 theVertexGenerator->Y()-theVertexGenerator->beamSpot().Y()+theBeamSpot.Y(),
00468 theVertexGenerator->Z()-theVertexGenerator->beamSpot().Z()+theBeamSpot.Z(),
00469 0.);
00470 }
00471
00472
00473 myFilter->setMainVertex(primaryVertexPosition+smearedVertex);
00474
00475
00476 int mainVertex = addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
00477
00478 HepMC::GenEvent::particle_const_iterator piter;
00479 HepMC::GenEvent::particle_const_iterator pbegin = myGenEvent.particles_begin();
00480 HepMC::GenEvent::particle_const_iterator pend = myGenEvent.particles_end();
00481
00482 int initialBarcode = 0;
00483 if ( pbegin != pend ) initialBarcode = (*pbegin)->barcode();
00484
00485 for ( piter = pbegin; piter != pend; ++piter ) {
00486
00487
00488 HepMC::GenParticle* p = *piter;
00489
00490 if ( !offset ) {
00491 (*theGenParticles)[nGenParticles++] = p;
00492 if ( nGenParticles/theGenSize*theGenSize == nGenParticles ) {
00493 theGenSize *= 2;
00494 theGenParticles->resize(theGenSize);
00495 }
00496
00497 }
00498
00499
00500
00501
00502 XYZTLorentzVector productionVertexPosition(0.,0.,0.,0.);
00503 HepMC::GenVertex* productionVertex = p->production_vertex();
00504 if ( productionVertex ) {
00505 unsigned productionMother = productionVertex->particles_in_size();
00506 if ( productionMother ) {
00507 unsigned motherId = (*(productionVertex->particles_in_const_begin()))->pdg_id();
00508 if ( abs(motherId) < 1000000 )
00509 productionVertexPosition =
00510 XYZTLorentzVector(productionVertex->position().x()/10.,
00511 productionVertex->position().y()/10.,
00512 productionVertex->position().z()/10.,
00513 productionVertex->position().t()/10.) + smearedVertex;
00514 }
00515 }
00516 if ( !myFilter->accept(productionVertexPosition) ) continue;
00517
00518 int abspdgId = abs(p->pdg_id());
00519 HepMC::GenVertex* endVertex = p->end_vertex();
00520
00521
00522
00523 bool testStable = p->status()%1000==1;
00524
00525
00526 if ( p->status() == 2 && abspdgId < 1000000) {
00527 if ( endVertex ) {
00528 XYZTLorentzVector decayPosition =
00529 XYZTLorentzVector(endVertex->position().x()/10.,
00530 endVertex->position().y()/10.,
00531 endVertex->position().z()/10.,
00532 endVertex->position().t()/10.) + smearedVertex;
00533
00534 if ( decayPosition.Perp2() > lateVertexPosition ) testStable = true;
00535 }
00536 }
00537
00538
00539 bool testDaugh = false;
00540 if ( !testStable &&
00541 p->status() == 2 &&
00542 endVertex &&
00543 endVertex->particles_out_size() ) {
00544 HepMC::GenVertex::particles_out_const_iterator firstDaughterIt =
00545 endVertex->particles_out_const_begin();
00546 HepMC::GenVertex::particles_out_const_iterator lastDaughterIt =
00547 endVertex->particles_out_const_end();
00548 for ( ; firstDaughterIt != lastDaughterIt ; ++firstDaughterIt ) {
00549 HepMC::GenParticle* daugh = *firstDaughterIt;
00550 if ( daugh->status()%1000==1 ) {
00551
00552 if (abspdgId == 11 || abspdgId == 13) {
00553 if ( endVertex ) {
00554 XYZTLorentzVector endVertexPosition = XYZTLorentzVector(endVertex->position().x()/10.,
00555 endVertex->position().y()/10.,
00556 endVertex->position().z()/10.,
00557 endVertex->position().t()/10.);
00558
00559 if ( endVertexPosition.Perp2() < lateVertexPosition ) {
00560 break;
00561 }
00562 }
00563 }
00564 testDaugh=true;
00565 break;
00566 }
00567 }
00568 }
00569
00570
00571 double dist = 0.;
00572 if ( !testStable && !testDaugh && p->production_vertex() ) {
00573 XYZTLorentzVector
00574 productionVertexPosition(p->production_vertex()->position().x()/10.,
00575 p->production_vertex()->position().y()/10.,
00576 p->production_vertex()->position().z()/10.,
00577 p->production_vertex()->position().t()/10.);
00578 dist = (primaryVertexPosition-productionVertexPosition).Vect().Mag2();
00579 }
00580 bool testDecay = ( dist > 1e-8 ) ? true : false;
00581
00582
00583 if ( testStable || testDaugh || testDecay ) {
00584
00585
00586
00587
00588
00589
00590 int motherBarcode = p->production_vertex() &&
00591 p->production_vertex()->particles_in_const_begin() !=
00592 p->production_vertex()->particles_in_const_end() ?
00593 (*(p->production_vertex()->particles_in_const_begin()))->barcode() : 0;
00594
00595 int originVertex =
00596 motherBarcode && myGenVertices[motherBarcode-initialBarcode] ?
00597 myGenVertices[motherBarcode-initialBarcode] : mainVertex;
00598
00599 XYZTLorentzVector momentum(p->momentum().px(),
00600 p->momentum().py(),
00601 p->momentum().pz(),
00602 p->momentum().e());
00603 RawParticle part(momentum, vertex(originVertex).position());
00604 part.setID(p->pdg_id());
00605
00606
00607
00608 int theTrack = testStable && p->end_vertex() ?
00609
00610 addSimTrack(&part,originVertex, nGenParts()-offset,p->end_vertex()) :
00611
00612 addSimTrack(&part,originVertex, nGenParts()-offset);
00613
00614 if (
00615
00616 !p->end_vertex() ||
00617
00618
00619 ( testStable && p->end_vertex() && !p->end_vertex()->particles_out_size() )
00620
00621 ) continue;
00622
00623
00624 XYZTLorentzVector decayVertex =
00625 XYZTLorentzVector(p->end_vertex()->position().x()/10.,
00626 p->end_vertex()->position().y()/10.,
00627 p->end_vertex()->position().z()/10.,
00628 p->end_vertex()->position().t()/10.) +
00629 smearedVertex;
00630
00631 int theVertex = addSimVertex(decayVertex,theTrack, FSimVertexType::DECAY_VERTEX);
00632
00633 if ( theVertex != -1 ) myGenVertices[p->barcode()-initialBarcode] = theVertex;
00634
00635
00636 }
00637 }
00638
00639 }
00640
00641 void
00642 FBaseSimEvent::addParticles(const reco::GenParticleCollection& myGenParticles) {
00643
00644
00645 unsigned int nParticles = myGenParticles.size();
00646 nGenParticles = nParticles;
00647
00648 if ( !nParticles ) return;
00649
00651 std::map<const reco::Candidate*,int> myGenVertices;
00652
00653
00654 int offset = nTracks();
00655
00656
00657 nGenParticles = 0;
00658 unsigned int ip = 0;
00659 if ( nParticles > 1 &&
00660 myGenParticles[0].pdgId() == 2212 &&
00661 myGenParticles[1].pdgId() == 2212 ) {
00662 ip = 2;
00663 nGenParticles = 2;
00664 }
00665
00666
00667 XYZTLorentzVector primaryVertex (myGenParticles[ip].vx(),
00668 myGenParticles[ip].vy(),
00669 myGenParticles[ip].vz(),
00670 0.);
00671
00672
00673 XYZTLorentzVector smearedVertex;
00674 if ( primaryVertex.mag() < 1E-8 ) {
00675 theVertexGenerator->generate();
00676 smearedVertex = XYZTLorentzVector(
00677 theVertexGenerator->X()-theVertexGenerator->beamSpot().X()+theBeamSpot.X(),
00678 theVertexGenerator->Y()-theVertexGenerator->beamSpot().Y()+theBeamSpot.Y(),
00679 theVertexGenerator->Z()-theVertexGenerator->beamSpot().Z()+theBeamSpot.Z(),
00680 0.);
00681 }
00682
00683
00684 myFilter->setMainVertex(primaryVertex+smearedVertex);
00685
00686
00687 int mainVertex = addSimVertex(myFilter->vertex(), -1, FSimVertexType::PRIMARY_VERTEX);
00688
00689
00690 for ( ; ip<nParticles; ++ip ) {
00691
00692
00693
00694 nGenParticles++;
00695 const reco::GenParticle& p = myGenParticles[ip];
00696
00697
00698
00699
00700 XYZTLorentzVector productionVertexPosition(0.,0.,0.,0.);
00701 const reco::Candidate* productionMother = p.numberOfMothers() ? p.mother(0) : 0;
00702 if ( productionMother ) {
00703 unsigned motherId = productionMother->pdgId();
00704 if ( abs(motherId) < 1000000 )
00705 productionVertexPosition = XYZTLorentzVector(p.vx(), p.vy(), p.vz(), 0.) + smearedVertex;
00706 }
00707 if ( !myFilter->accept(productionVertexPosition) ) continue;
00708
00709
00710
00711 bool testStable = p.status()%1000==1;
00712
00713
00714 if ( p.status() == 2 && abs(p.pdgId()) < 1000000 ) {
00715 unsigned int nDaughters = p.numberOfDaughters();
00716 if ( nDaughters ) {
00717 const reco::Candidate* daughter = p.daughter(0);
00718 XYZTLorentzVector decayPosition =
00719 XYZTLorentzVector(daughter->vx(), daughter->vy(), daughter->vz(), 0.) + smearedVertex;
00720
00721 if ( decayPosition.Perp2() > lateVertexPosition ) testStable = true;
00722 }
00723 }
00724
00725
00726 bool testDaugh = false;
00727 unsigned int nDaughters = p.numberOfDaughters();
00728 if ( !testStable &&
00729
00730 nDaughters ) {
00731 for ( unsigned iDaughter=0; iDaughter<nDaughters; ++iDaughter ) {
00732 const reco::Candidate* daughter = p.daughter(iDaughter);
00733 if ( daughter->status()%1000==1 ) {
00734 testDaugh=true;
00735 break;
00736 }
00737 }
00738 }
00739
00740
00741 double dist = 0.;
00742 if ( !testStable && !testDaugh ) {
00743 XYZTLorentzVector productionVertex(p.vx(),p.vy(),p.vz(),0.);
00744 dist = (primaryVertex-productionVertex).Vect().Mag2();
00745 }
00746 bool testDecay = ( dist > 1e-8 ) ? true : false;
00747
00748
00749 if ( testStable || testDaugh || testDecay ) {
00750
00751 const reco::Candidate* mother = p.numberOfMothers() ? p.mother(0) : 0;
00752
00753 int originVertex =
00754 mother &&
00755 myGenVertices.find(mother) != myGenVertices.end() ?
00756 myGenVertices[mother] : mainVertex;
00757
00758 XYZTLorentzVector momentum(p.px(),p.py(),p.pz(),p.energy());
00759 RawParticle part(momentum, vertex(originVertex).position());
00760 part.setID(p.pdgId());
00761
00762
00763 int theTrack = addSimTrack(&part,originVertex, nGenParts()-offset);
00764
00765
00766 if ( !nDaughters ) continue;
00767 const reco::Candidate* daughter = p.daughter(0);
00768
00769
00770 XYZTLorentzVector decayVertex =
00771 XYZTLorentzVector(daughter->vx(), daughter->vy(),
00772 daughter->vz(), 0.) + smearedVertex;
00773 int theVertex = addSimVertex(decayVertex,theTrack, FSimVertexType::DECAY_VERTEX);
00774
00775 if ( theVertex != -1 ) myGenVertices[&p] = theVertex;
00776
00777
00778 }
00779 }
00780
00781
00782
00783
00784 }
00785
00786 int
00787 FBaseSimEvent::addSimTrack(const RawParticle* p, int iv, int ig,
00788 const HepMC::GenVertex* ev) {
00789
00790
00791
00792 if ( !myFilter->accept(p) && ig >= -1 ) return -1;
00793
00794
00795 int trackId = nSimTracks++;
00796 if ( nSimTracks/theTrackSize*theTrackSize == nSimTracks ) {
00797 theTrackSize *= 2;
00798 theSimTracks->resize(theTrackSize);
00799 }
00800
00801
00802 vertex(iv).addDaughter(trackId);
00803 if ( !vertex(iv).noParent() ) {
00804 track(vertex(iv).parent().id()).addDaughter(trackId);
00805
00806 if ( ig == -1 ) {
00807 int motherId = track(vertex(iv).parent().id()).genpartIndex();
00808 if ( motherId < -1 ) ig = motherId;
00809 }
00810 }
00811
00812
00813 (*theSimTracks)[trackId] = ev ?
00814
00815 FSimTrack(p,iv,ig,trackId,this,
00816 ev->position().t()/10.
00817 * p->PDGmass()
00818 / std::sqrt(p->momentum().Vect().Mag2())) :
00819
00820 FSimTrack(p,iv,ig,trackId,this);
00821
00822 return trackId;
00823
00824 }
00825
00826 int
00827 FBaseSimEvent::addSimVertex(const XYZTLorentzVector& v, int im, FSimVertexType::VertexType type) {
00828
00829
00830 if ( !myFilter->accept(v) ) return -1;
00831
00832
00833 int vertexId = nSimVertices++;
00834 if ( nSimVertices/theVertexSize*theVertexSize == nSimVertices ) {
00835 theVertexSize *= 2;
00836 theSimVertices->resize(theVertexSize);
00837 theFSimVerticesType->resize(theVertexSize);
00838 }
00839
00840
00841 if ( im !=-1 ) track(im).setEndVertex(vertexId);
00842
00843
00844 (*theSimVertices)[vertexId] = FSimVertex(v,im,vertexId,this);
00845
00846 (*theFSimVerticesType)[vertexId] = FSimVertexType(type);
00847
00848 return vertexId;
00849
00850 }
00851
00852 void
00853 FBaseSimEvent::printMCTruth(const HepMC::GenEvent& myGenEvent) {
00854
00855 std::cout << "Id Gen Name eta phi pT E Vtx1 "
00856 << " x y z "
00857 << "Moth Vtx2 eta phi R Z Da1 Da2 Ecal?" << std::endl;
00858
00859 for ( HepMC::GenEvent::particle_const_iterator
00860 piter = myGenEvent.particles_begin();
00861 piter != myGenEvent.particles_end();
00862 ++piter ) {
00863
00864 HepMC::GenParticle* p = *piter;
00865
00866 int partId = p->pdg_id();
00867 std::string name;
00868
00869 if ( pdt->particle(ParticleID(partId)) !=0 ) {
00870 name = (pdt->particle(ParticleID(partId)))->name();
00871 } else {
00872 name = "none";
00873 }
00874
00875 XYZTLorentzVector momentum1(p->momentum().px(),
00876 p->momentum().py(),
00877 p->momentum().pz(),
00878 p->momentum().e());
00879
00880 int vertexId1 = 0;
00881
00882 if ( !p->production_vertex() ) continue;
00883
00884 XYZVector vertex1 (p->production_vertex()->position().x()/10.,
00885 p->production_vertex()->position().y()/10.,
00886 p->production_vertex()->position().z()/10.);
00887 vertexId1 = p->production_vertex()->barcode();
00888
00889 std::cout.setf(std::ios::fixed, std::ios::floatfield);
00890 std::cout.setf(std::ios::right, std::ios::adjustfield);
00891
00892 std::cout << std::setw(4) << p->barcode() << " "
00893 << name;
00894
00895 for(unsigned int k=0;k<11-name.length() && k<12; k++) std::cout << " ";
00896
00897 double eta = momentum1.eta();
00898 if ( eta > +10. ) eta = +10.;
00899 if ( eta < -10. ) eta = -10.;
00900 std::cout << std::setw(6) << std::setprecision(2) << eta << " "
00901 << std::setw(6) << std::setprecision(2) << momentum1.phi() << " "
00902 << std::setw(7) << std::setprecision(2) << momentum1.pt() << " "
00903 << std::setw(7) << std::setprecision(2) << momentum1.e() << " "
00904 << std::setw(4) << vertexId1 << " "
00905 << std::setw(6) << std::setprecision(1) << vertex1.x() << " "
00906 << std::setw(6) << std::setprecision(1) << vertex1.y() << " "
00907 << std::setw(6) << std::setprecision(1) << vertex1.z() << " ";
00908
00909 const HepMC::GenParticle* mother =
00910 *(p->production_vertex()->particles_in_const_begin());
00911
00912 if ( mother )
00913 std::cout << std::setw(4) << mother->barcode() << " ";
00914 else
00915 std::cout << " " ;
00916
00917 if ( p->end_vertex() ) {
00918 XYZTLorentzVector vertex2(p->end_vertex()->position().x()/10.,
00919 p->end_vertex()->position().y()/10.,
00920 p->end_vertex()->position().z()/10.,
00921 p->end_vertex()->position().t()/10.);
00922 int vertexId2 = p->end_vertex()->barcode();
00923
00924 std::vector<const HepMC::GenParticle*> children;
00925 HepMC::GenVertex::particles_out_const_iterator firstDaughterIt =
00926 p->end_vertex()->particles_out_const_begin();
00927 HepMC::GenVertex::particles_out_const_iterator lastDaughterIt =
00928 p->end_vertex()->particles_out_const_end();
00929 for ( ; firstDaughterIt != lastDaughterIt ; ++firstDaughterIt ) {
00930 children.push_back(*firstDaughterIt);
00931 }
00932
00933 std::cout << std::setw(4) << vertexId2 << " "
00934 << std::setw(6) << std::setprecision(2) << vertex2.eta() << " "
00935 << std::setw(6) << std::setprecision(2) << vertex2.phi() << " "
00936 << std::setw(5) << std::setprecision(1) << vertex2.pt() << " "
00937 << std::setw(6) << std::setprecision(1) << vertex2.z() << " ";
00938 for ( unsigned id=0; id<children.size(); ++id )
00939 std::cout << std::setw(4) << children[id]->barcode() << " ";
00940 }
00941 std::cout << std::endl;
00942
00943 }
00944
00945 }
00946
00947 void
00948 FBaseSimEvent::print() const {
00949
00950 std::cout << " Id Gen Name eta phi pT E Vtx1 "
00951 << " x y z "
00952 << "Moth Vtx2 eta phi R Z Daughters Ecal?" << std::endl;
00953
00954 for( int i=0; i<(int)nTracks(); i++ )
00955 std::cout << track(i) << std::endl;
00956
00957 for( int i=0; i<(int)nVertices(); i++ )
00958 std::cout << "i = " << i << " " << vertexType(i) << std::endl;
00959
00960
00961
00962 }
00963
00964 void
00965 FBaseSimEvent::clear() {
00966
00967 nSimTracks = 0;
00968 nSimVertices = 0;
00969 nGenParticles = 0;
00970 nChargedParticleTracks = 0;
00971
00972 }
00973
00974 void
00975 FBaseSimEvent::addChargedTrack(int id) {
00976 (*theChargedTracks)[nChargedParticleTracks++] = id;
00977 if ( nChargedParticleTracks/theChargedSize*theChargedSize
00978 == nChargedParticleTracks ) {
00979 theChargedSize *= 2;
00980 theChargedTracks->resize(theChargedSize);
00981 }
00982 }
00983
00984 int
00985 FBaseSimEvent::chargedTrack(int id) const {
00986 if (id>=0 && id<(int)nChargedParticleTracks)
00987 return (*theChargedTracks)[id];
00988 else
00989 return -1;
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 const HepMC::GenParticle*
01005 FBaseSimEvent::embdGenpart(int i) const {
01006 return (*theGenParticles)[i];
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020