00001
00002 #include "DataFormats/DetId/interface/DetId.h"
00003 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00004 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00005 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00006 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00007 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00008 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00009 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00010 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00011
00012 #include "FWCore/Framework/interface/MakerMacros.h"
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014
00015 #include "SimDataFormats/EncodedEventId/interface/EncodedEventId.h"
00016 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
00017 #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h"
00018
00019 #include "SimGeneral/TrackingAnalysis/interface/TrackingTruthProducer.h"
00020
00021 typedef edm::Ref<edm::HepMCProduct, HepMC::GenParticle > GenParticleRef;
00022 typedef edm::Ref<edm::HepMCProduct, HepMC::GenVertex > GenVertexRef;
00023 typedef math::XYZTLorentzVectorD LorentzVector;
00024 typedef math::XYZPoint Vector;
00025
00026 TrackingTruthProducer::TrackingTruthProducer(const edm::ParameterSet & config) :
00027 pSimHitSelector_(config), pixelPSimHitSelector_(config), trackerPSimHitSelector_(config), muonPSimHitSelector_(config)
00028 {
00029
00030 dataLabels_ = config.getParameter<std::vector<std::string> >("HepMCDataLabels");
00031 useMultipleHepMCLabels_ = config.getParameter<bool>("useMultipleHepMCLabels");
00032
00033 distanceCut_ = config.getParameter<double>("vertexDistanceCut");
00034 volumeRadius_ = config.getParameter<double>("volumeRadius");
00035 volumeZ_ = config.getParameter<double>("volumeZ");
00036 mergedBremsstrahlung_ = config.getParameter<bool>("mergedBremsstrahlung");
00037 removeDeadModules_ = config.getParameter<bool>("removeDeadModules");
00038 simHitLabel_ = config.getParameter<std::string>("simHitLabel");
00039
00040
00041 if ( config.exists("select") )
00042 {
00043 edm::ParameterSet param = config.getParameter<edm::ParameterSet>("select");
00044 selector_ = TrackingParticleSelector(
00045 param.getParameter<double>("ptMinTP"),
00046 param.getParameter<double>("minRapidityTP"),
00047 param.getParameter<double>("maxRapidityTP"),
00048 param.getParameter<double>("tipTP"),
00049 param.getParameter<double>("lipTP"),
00050 param.getParameter<int>("minHitTP"),
00051 param.getParameter<bool>("signalOnlyTP"),
00052 param.getParameter<bool>("chargedOnlyTP"),
00053 param.getParameter<bool>("stableOnlyTP"),
00054 param.getParameter<std::vector<int> >("pdgIdTP")
00055 );
00056 selectorFlag_ = true;
00057 }
00058 else
00059 selectorFlag_ = false;
00060
00061 MessageCategory_ = "TrackingTruthProducer";
00062
00063 edm::LogInfo (MessageCategory_) << "Setting up TrackingTruthProducer";
00064 edm::LogInfo (MessageCategory_) << "Vertex distance cut set to " << distanceCut_ << " mm";
00065 edm::LogInfo (MessageCategory_) << "Volume radius set to " << volumeRadius_ << " mm";
00066 edm::LogInfo (MessageCategory_) << "Volume Z set to " << volumeZ_ << " mm";
00067
00068 if (useMultipleHepMCLabels_) edm::LogInfo (MessageCategory_) << "Collecting generator information from pileup.";
00069 if (mergedBremsstrahlung_) edm::LogInfo (MessageCategory_) << "Merging electrom bremsstralung";
00070 if (removeDeadModules_) edm::LogInfo (MessageCategory_) << "Removing psimhit from dead modules";
00071
00072 if (!mergedBremsstrahlung_)
00073 {
00074 produces<TrackingVertexCollection>();
00075 produces<TrackingParticleCollection>();
00076 }
00077 else
00078 {
00079 produces<TrackingVertexCollection>();
00080 produces<TrackingParticleCollection>();
00081 produces<TrackingVertexCollection>("MergedTrackTruth");
00082 produces<TrackingParticleCollection>("MergedTrackTruth");
00083 }
00084 }
00085
00086
00087 void TrackingTruthProducer::produce(edm::Event &event, const edm::EventSetup & setup)
00088 {
00089
00090 hepMCProducts_.clear();
00091
00092
00093 edm::Handle<edm::HepMCProduct> hepMCHandle;
00094
00095 for (std::vector<std::string>::const_iterator source = dataLabels_.begin(); source != dataLabels_.end(); ++source)
00096 {
00097 if ( event.getByLabel(*source, hepMCHandle) )
00098 {
00099 hepMCProducts_.push_back(hepMCHandle);
00100 edm::LogInfo (MessageCategory_) << "Using HepMC source " << *source;
00101 if (!useMultipleHepMCLabels_) break;
00102 }
00103 }
00104
00105 if ( hepMCProducts_.empty() )
00106 {
00107 edm::LogWarning (MessageCategory_) << "No HepMC source found";
00108 return;
00109 }
00110 else if (hepMCProducts_.size() > 1 || useMultipleHepMCLabels_)
00111 {
00112 edm::LogInfo (MessageCategory_) << "You are using more than one HepMC source.";
00113 edm::LogInfo (MessageCategory_) << "If the labels are not in the same order as the events in the crossing frame (i.e. signal, pileup(s) ) ";
00114 edm::LogInfo (MessageCategory_) << "or there are fewer labels than events in the crossing frame";
00115 edm::LogInfo (MessageCategory_) << MessageCategory_ << " may try to access data in the wrong HepMCProduct and crash.";
00116 }
00117
00118
00119 edm::Handle<CrossingFrame<SimTrack> > cfSimTracks;
00120 event.getByLabel("mix", simHitLabel_, cfSimTracks);
00121
00122
00123 simTracks_ = std::auto_ptr<MixCollection<SimTrack> >( new MixCollection<SimTrack>(cfSimTracks.product()) );
00124
00125
00126 edm::Handle<CrossingFrame<SimVertex> > cfSimVertexes;
00127 event.getByLabel("mix", simHitLabel_, cfSimVertexes);
00128
00129
00130 simVertexes_ = std::auto_ptr<MixCollection<SimVertex> >( new MixCollection<SimVertex>(cfSimVertexes.product()) );
00131
00132
00133 trackingParticles_ = std::auto_ptr<TrackingParticleCollection>( new TrackingParticleCollection );
00134 trackingVertexes_ = std::auto_ptr<TrackingVertexCollection>( new TrackingVertexCollection );
00135
00136
00137 refTrackingParticles_ = event.getRefBeforePut<TrackingParticleCollection>();
00138 refTrackingVertexes_ = event.getRefBeforePut<TrackingVertexCollection>();
00139
00140
00141 if (removeDeadModules_)
00142 {
00143 pSimHits_.clear();
00144 pixelPSimHitSelector_.select(pSimHits_, event, setup);
00145 trackerPSimHitSelector_.select(pSimHits_, event, setup);
00146 muonPSimHitSelector_.select(pSimHits_, event, setup);
00147 }
00148 else
00149 {
00150 pSimHits_.clear();
00151 pSimHitSelector_.select(pSimHits_, event, setup);
00152 }
00153
00154
00155 associator(pSimHits_, trackIdToHits_);
00156
00157
00158 associator(simTracks_, trackIdToIndex_);
00159
00160
00161 associator(simVertexes_, vertexIdToIndex_);
00162
00163 createTrackingTruth();
00164
00165 if (mergedBremsstrahlung_)
00166 {
00167
00168 mergedTrackingParticles_ = std::auto_ptr<TrackingParticleCollection>( new TrackingParticleCollection );
00169 mergedTrackingVertexes_ = std::auto_ptr<TrackingVertexCollection>( new TrackingVertexCollection );
00170
00171
00172 refMergedTrackingParticles_ = event.getRefBeforePut<TrackingParticleCollection>("MergedTrackTruth");
00173 refMergedTrackingVertexes_ = event.getRefBeforePut<TrackingVertexCollection>("MergedTrackTruth");
00174
00175
00176 mergeBremsstrahlung();
00177
00178
00179 event.put(mergedTrackingParticles_, "MergedTrackTruth");
00180 event.put(mergedTrackingVertexes_, "MergedTrackTruth");
00181 event.put(trackingParticles_);
00182 event.put(trackingVertexes_);
00183 }
00184 else
00185 {
00186
00187 event.put(trackingParticles_);
00188 event.put(trackingVertexes_);
00189 }
00190 }
00191
00192
00193 void TrackingTruthProducer::associator(
00194 std::vector<PSimHit> const & pSimHits,
00195 EncodedTruthIdToIndexes & association
00196 )
00197 {
00198
00199 association.clear();
00200
00201
00202 for (std::size_t i = 0; i < pSimHits.size(); ++i)
00203 {
00204 EncodedTruthIdToIndexes::key_type objectId = EncodedTruthIdToIndexes::key_type(pSimHits[i].eventId(), pSimHits[i].trackId());
00205 association.insert( std::make_pair(objectId, i) );
00206 }
00207 }
00208
00209
00210 void TrackingTruthProducer::associator(
00211 std::auto_ptr<MixCollection<SimTrack> > const & mixCollection,
00212 EncodedTruthIdToIndex & association
00213 )
00214 {
00215 int index = 0;
00216
00217 association.clear();
00218
00219 for (MixCollection<SimTrack>::MixItr iterator = mixCollection->begin(); iterator != mixCollection->end(); ++iterator, ++index)
00220 {
00221 EncodedTruthId objectId = EncodedTruthId(iterator->eventId(), iterator->trackId());
00222 association.insert( std::make_pair(objectId, index) );
00223 }
00224 }
00225
00226
00227 void TrackingTruthProducer::associator(
00228 std::auto_ptr<MixCollection<SimVertex> > const & mixCollection,
00229 EncodedTruthIdToIndex & association
00230 )
00231 {
00232 int index = 0;
00233
00234
00235 bool useVertexId = true;
00236 EncodedEventIdToIndex vertexId;
00237 EncodedEventId oldEventId;
00238 unsigned int oldVertexId = 0;
00239
00240
00241 for (MixCollection<SimVertex>::MixItr iterator = mixCollection->begin(); iterator != mixCollection->end(); ++iterator, ++index)
00242 {
00243 if (!index || iterator->eventId() != oldEventId)
00244 {
00245 oldEventId = iterator->eventId();
00246 oldVertexId = iterator->vertexId();
00247 continue;
00248 }
00249
00250 if ( iterator->vertexId() == oldVertexId )
00251 {
00252 edm::LogWarning(MessageCategory_) << "Multiple vertexId found, no using vertexId.";
00253 useVertexId = false;
00254 break;
00255 }
00256 }
00257
00258
00259 index = 0;
00260
00261
00262 association.clear();
00263
00264
00265 for (MixCollection<SimVertex>::MixItr iterator = mixCollection->begin(); iterator != mixCollection->end(); ++iterator, ++index)
00266 {
00267 EncodedTruthId objectId;
00268 if (useVertexId)
00269 objectId = EncodedTruthId(iterator->eventId(), iterator->vertexId());
00270 else
00271 objectId = EncodedTruthId(iterator->eventId(), vertexId[iterator->eventId()]++);
00272 association.insert( std::make_pair(objectId, index) );
00273 }
00274 }
00275
00276
00277 void TrackingTruthProducer::mergeBremsstrahlung()
00278 {
00279 unsigned int index = 0;
00280
00281 std::set<unsigned int> excludedTV, excludedTP;
00282
00283
00284 for (TrackingVertexCollection::iterator iVC = trackingVertexes_->begin(); iVC != trackingVertexes_->end(); ++iVC, ++index)
00285 {
00286
00287 if ( isBremsstrahlungVertex(*iVC, trackingParticles_) )
00288 {
00289
00290 TrackingParticle * track = &trackingParticles_->at(iVC->sourceTracks_begin()->key());
00291
00292 TrackingParticleRef trackRef = *iVC->sourceTracks_begin();
00293
00294 TrackingParticle * daughter = 0;
00295
00296 TrackingParticleRef daughterRef;
00297
00298
00299 for (TrackingVertex::tp_iterator idaughter = iVC->daughterTracks_begin(); idaughter != iVC->daughterTracks_end(); ++idaughter)
00300 {
00301 TrackingParticle * pointer = &trackingParticles_->at(idaughter->key());
00302 if ( std::abs( pointer->pdgId() ) == 11 )
00303 {
00304
00305 daughter = pointer;
00306
00307 daughterRef = *idaughter;
00308 }
00309 else if ( pointer->pdgId() == 22 )
00310 {
00311
00312 pointer->clearParentVertex();
00313
00314 pointer->setParentVertex( track->parentVertex() );
00315
00316 TrackingVertex * vertex = &trackingVertexes_->at( track->parentVertex().key() );
00317
00318 vertex->addDaughterTrack( *idaughter );
00319 }
00320 }
00321
00322
00323
00324
00325 for (TrackingParticle::g4t_iterator isegment = daughter->g4Track_begin(); isegment != daughter->g4Track_end(); ++isegment)
00326 track->addG4Track(*isegment);
00327
00328
00329 for (std::vector<PSimHit>::const_iterator ihit = daughter->pSimHit_begin(); ihit != daughter->pSimHit_end(); ++ihit)
00330 track->addPSimHit(*ihit);
00331
00332
00333 TrackingVertexRefVector decayVertices( track->decayVertices() );
00334
00335
00336 track->clearDecayVertices();
00337
00338
00339 for (TrackingVertexRefVector::const_iterator idecay = decayVertices.begin(); idecay != decayVertices.end(); ++idecay)
00340 if ( (*idecay).key() != index ) track->addDecayVertex(*idecay);
00341
00342
00343 for (TrackingParticle::tv_iterator idecay = daughter->decayVertices_begin(); idecay != daughter->decayVertices_end(); ++idecay)
00344 {
00345
00346 track->addDecayVertex(*idecay);
00347
00348 TrackingVertex * vertex = &trackingVertexes_->at( idecay->key() );
00349
00350 TrackingParticleRefVector sources( vertex->sourceTracks() );
00351
00352 vertex->clearParentTracks();
00353
00354 for (TrackingVertex::tp_iterator isource = sources.begin(); isource != sources.end(); ++isource)
00355 if (*isource != daughterRef)
00356 vertex->addParentTrack(*isource);
00357
00358 vertex->addParentTrack(trackRef);
00359 }
00360
00361
00362 excludedTV.insert(index);
00363
00364
00365 excludedTP.insert( daughterRef.key() );
00366 }
00367 }
00368
00369 edm::LogInfo(MessageCategory_) << "Generating the merged collection." << std::endl;
00370
00371
00372 mergedTrackingParticles_->reserve(trackingParticles_->size());
00373 mergedTrackingVertexes_->reserve(trackingVertexes_->size());
00374
00375 index = 0;
00376 std::map<unsigned int, unsigned int> vertexMap;
00377
00378
00379 for (TrackingVertexCollection::const_iterator iVC = trackingVertexes_->begin(); iVC != trackingVertexes_->end(); ++iVC, ++index)
00380 {
00381 if ( excludedTV.find(index) != excludedTV.end() ) continue;
00382
00383 vertexMap.insert( std::make_pair(index, mergedTrackingVertexes_->size()) );
00384
00385 TrackingVertex newVertex = (*iVC);
00386 newVertex.clearDaughterTracks();
00387 newVertex.clearParentTracks();
00388 mergedTrackingVertexes_->push_back(newVertex);
00389 }
00390
00391 index = 0;
00392
00393
00394 for (TrackingParticleCollection::const_iterator iTP = trackingParticles_->begin(); iTP != trackingParticles_->end(); ++iTP, ++index)
00395 {
00396 if ( excludedTP.find(index) != excludedTP.end() ) continue;
00397
00398 TrackingVertexRef sourceV = iTP->parentVertex();
00399 TrackingVertexRefVector decayVs = iTP->decayVertices();
00400 TrackingParticle newTrack = *iTP;
00401
00402 newTrack.clearParentVertex();
00403 newTrack.clearDecayVertices();
00404
00405
00406
00407
00408 unsigned int parentIndex = vertexMap[sourceV.key()];
00409
00410 unsigned int tIndex = mergedTrackingParticles_->size();
00411
00412
00413 newTrack.setParentVertex( TrackingVertexRef(refMergedTrackingVertexes_, parentIndex) );
00414
00415 (mergedTrackingVertexes_->at(parentIndex)).addDaughterTrack(TrackingParticleRef(refMergedTrackingParticles_, tIndex));
00416
00417 for (TrackingVertexRefVector::const_iterator iDecayV = decayVs.begin(); iDecayV != decayVs.end(); ++iDecayV)
00418 {
00419
00420 unsigned int daughterIndex = vertexMap[iDecayV->key()];
00421
00422 newTrack.addDecayVertex( TrackingVertexRef(refMergedTrackingVertexes_, daughterIndex) );
00423
00424 (mergedTrackingVertexes_->at(daughterIndex)).addParentTrack( TrackingParticleRef(refMergedTrackingParticles_, tIndex) );
00425 }
00426
00427 mergedTrackingParticles_->push_back(newTrack);
00428 }
00429 }
00430
00431
00432 bool TrackingTruthProducer::isBremsstrahlungVertex(
00433 TrackingVertex const & vertex,
00434 std::auto_ptr<TrackingParticleCollection> & tPC
00435 )
00436 {
00437 const TrackingParticleRefVector parents(vertex.sourceTracks());
00438
00439
00440 if ( parents.size() != 1)
00441 return false;
00442
00443
00444 if ( std::abs( tPC->at(parents.begin()->key()).pdgId() ) != 11 )
00445 return false;
00446
00447 int nElectrons = 0;
00448 int nPhotons = 0;
00449 int nOthers = 0;
00450
00451
00452 for ( TrackingVertex::tp_iterator it = vertex.daughterTracks_begin(); it != vertex.daughterTracks_end(); ++it )
00453 {
00454
00455 if ( parents[0] == *it )
00456 return false;
00457
00458 if ( std::abs( tPC->at(it->key()).pdgId() ) == 11 )
00459 nElectrons++;
00460 else if ( tPC->at(it->key()).pdgId() == 22 )
00461 nPhotons++;
00462 else
00463 nOthers++;
00464 }
00465
00466
00467 if (nElectrons == 1 && nPhotons >= 0 && nOthers == 0)
00468 return true;
00469
00470 return false;
00471 }
00472
00473
00474 void TrackingTruthProducer::createTrackingTruth()
00475 {
00476
00477 eventIdCounter_.clear();
00478
00479
00480 std::map<int,std::size_t> vetoedTracks;
00481
00482
00483 std::map<int,std::size_t> vetoedSimVertexes;
00484
00485 for (int simTrackIndex = 0; simTrackIndex != simTracks_->size(); ++simTrackIndex)
00486 {
00487
00488 if ( vetoedTracks.find(simTrackIndex) != vetoedTracks.end() ) continue;
00489
00490 SimTrack const & simTrack = simTracks_->getObject(simTrackIndex);
00491
00492 TrackingParticle trackingParticle;
00493
00494
00495
00496 if ( setTrackingParticle(simTrack, trackingParticle) )
00497 {
00498
00499 SimTrack const * currentSimTrack = & simTrack;
00500
00501
00502 int trackingParticleIndex = -1;
00503 int trackingVertexIndex = -1;
00504
00505 do
00506 {
00507
00508
00509 if (trackingParticleIndex >= 0)
00510 {
00511 setTrackingParticle(*currentSimTrack, trackingParticle);
00512
00513
00514 trackingParticleIndex = trackingParticles_->size();
00515
00516 trackingParticles_->push_back(trackingParticle);
00517
00518
00519 trackingParticles_->at(trackingParticleIndex).addDecayVertex(
00520 TrackingVertexRef(refTrackingVertexes_, trackingVertexIndex)
00521 );
00522
00523
00524 trackingVertexes_->at(trackingVertexIndex).addParentTrack(
00525 TrackingParticleRef(refTrackingParticles_, trackingParticleIndex)
00526 );
00527 }
00528 else
00529 {
00530
00531 trackingParticleIndex = trackingParticles_->size();
00532
00533 trackingParticles_->push_back(trackingParticle);
00534
00535 vetoedTracks.insert( std::make_pair(simTrackIndex, trackingParticleIndex) );
00536 }
00537
00538
00539 if (currentSimTrack->noVertex()) break;
00540
00541
00542 unsigned int parentSimVertexIndex = vertexIdToIndex_[
00543 EncodedTruthId(
00544 currentSimTrack->eventId(),
00545 currentSimTrack->vertIndex()
00546 )
00547 ];
00548
00549 TrackingVertex trackingVertex;
00550
00551 SimVertex const * parentSimVertex = & simVertexes_->getObject(parentSimVertexIndex);
00552
00553 bool vetoSimVertex = vetoedSimVertexes.find(parentSimVertexIndex) != vetoedSimVertexes.end();
00554
00555
00556 if ( !vetoSimVertex )
00557 {
00558
00559 trackingVertexIndex = setTrackingVertex(*parentSimVertex, trackingVertex);
00560
00561
00562 if (trackingVertexIndex < 0)
00563 {
00564
00565 trackingVertexIndex = trackingVertexes_->size();
00566
00567 trackingVertexes_->push_back(trackingVertex);
00568 }
00569 else
00570 {
00571
00572 const LorentzVector & position = trackingVertexes_->at(trackingVertexIndex).position();
00573 Vector xyz = Vector(position.x(), position.y(), position.z());
00574 double t = position.t();
00575
00576 trackingParticles_->at(trackingParticleIndex).setVertex(xyz, t);
00577 }
00578
00579 vetoedSimVertexes.insert( std::make_pair(parentSimVertexIndex, trackingVertexIndex) );
00580 }
00581 else
00582 trackingVertexIndex = vetoedSimVertexes[parentSimVertexIndex];
00583
00584
00585 trackingParticles_->at(trackingParticleIndex).setParentVertex(
00586 TrackingVertexRef(refTrackingVertexes_, trackingVertexIndex)
00587 );
00588
00589
00590 trackingVertexes_->at(trackingVertexIndex).addDaughterTrack(
00591 TrackingParticleRef(refTrackingParticles_, trackingParticleIndex)
00592 );
00593
00594
00595 if (parentSimVertex->noParent() || vetoSimVertex) break;
00596
00597
00598 unsigned int nextSimTrackIndex = trackIdToIndex_[
00599 EncodedTruthId(
00600 currentSimTrack->eventId(),
00601 parentSimVertex->parentIndex()
00602 )
00603 ];
00604
00605
00606 if ( vetoedTracks.find(nextSimTrackIndex) != vetoedTracks.end() )
00607 {
00608
00609 trackingVertexes_->at(trackingVertexIndex).addParentTrack(
00610 TrackingParticleRef(refTrackingParticles_, vetoedTracks[nextSimTrackIndex])
00611 );
00612
00613 trackingParticles_->at(vetoedTracks[nextSimTrackIndex]).addDecayVertex(
00614 TrackingVertexRef(refTrackingVertexes_, trackingVertexIndex)
00615 );
00616 break;
00617 }
00618
00619
00620 vetoedTracks.insert( std::make_pair(nextSimTrackIndex, trackingParticleIndex) );
00621
00622
00623 currentSimTrack = & simTracks_->getObject(nextSimTrackIndex);
00624 }
00625 while (!currentSimTrack->noVertex());
00626 }
00627 }
00628 }
00629
00630
00631 bool TrackingTruthProducer::setTrackingParticle(
00632 SimTrack const & simTrack,
00633 TrackingParticle & trackingParticle
00634 )
00635 {
00636
00637 EncodedEventId trackEventId = simTrack.eventId();
00638
00639 EncodedTruthId simTrackId = EncodedTruthId( trackEventId, simTrack.trackId() );
00640
00641
00642 LorentzVector position;
00643
00644 if (simTrack.noVertex())
00645 position = LorentzVector(0, 0, 0, 0);
00646 else
00647 position = simVertexes_->getObject(simTrack.vertIndex()). position();
00648
00649
00650 int status = -99;
00651 int pdgId = simTrack.type();
00652
00653 int genParticleIndex = simTrack.genpartIndex();
00654 bool signalEvent = (trackEventId.event() == 0 && trackEventId.bunchCrossing() == 0);
00655
00656
00657
00658
00659 edm::Handle<edm::HepMCProduct> hepmc;
00660
00661 if (genParticleIndex >= 0 && (signalEvent || useMultipleHepMCLabels_) )
00662 {
00663
00664 hepmc = (useMultipleHepMCLabels_) ? hepMCProducts_.at(trackEventId.rawId()) : hepmc = hepMCProducts_.at(0);
00665
00666 const HepMC::GenParticle * genParticle = hepmc->GetEvent()->barcode_to_particle(genParticleIndex);
00667
00668 if (genParticle)
00669 {
00670 status = genParticle->status();
00671 pdgId = genParticle->pdg_id();
00672 }
00673 }
00674
00675
00676 trackingParticle = TrackingParticle(
00677 (char) simTrack.charge(),
00678 simTrack.momentum(),
00679 Vector(position.x(), position.y(), position.z()),
00680 position.t(),
00681 pdgId,
00682 status,
00683 trackEventId
00684 );
00685
00686 bool init = true;
00687
00688 int processType = 0;
00689 int particleType = 0;
00690
00691
00692
00693 int totalSimHits = 0;
00694 int oldLayer = 0;
00695 int newLayer = 0;
00696 int oldDetector = 0;
00697 int newDetector = 0;
00698
00699
00700 for (
00701 EncodedTruthIdToIndexes::const_iterator iEntry = trackIdToHits_.lower_bound(simTrackId);
00702 iEntry != trackIdToHits_.upper_bound(simTrackId);
00703 ++iEntry
00704 )
00705 {
00706
00707 PSimHit const & pSimHit = pSimHits_.at(iEntry->second);
00708
00709
00710 if (init)
00711 {
00712 processType = pSimHit.processType();
00713 particleType = pSimHit.particleType();
00714 init = false;
00715 }
00716
00717
00718 if (processType == pSimHit.processType() && particleType == pSimHit.particleType() && pdgId == pSimHit.particleType() )
00719 {
00720 trackingParticle.addPSimHit(pSimHit);
00721
00722 unsigned int detectorIdIndex = pSimHit.detUnitId();
00723 DetId detectorId = DetId(detectorIdIndex);
00724 oldLayer = newLayer;
00725 oldDetector = newDetector;
00726 newLayer = LayerFromDetid(detectorIdIndex);
00727 newDetector = detectorId.subdetId();
00728
00729
00730
00731 if ( ( oldLayer != newLayer || (oldLayer==newLayer && oldDetector!=newDetector ) ) && newLayer != 0 ) totalSimHits++;
00732 }
00733 }
00734
00735
00736 trackingParticle.setMatchedHit(totalSimHits);
00737
00738
00739 trackingParticle.addG4Track(simTrack);
00740
00741
00742 if ( genParticleIndex >= 0 && (signalEvent || useMultipleHepMCLabels_) )
00743 trackingParticle.addGenParticle( GenParticleRef(hepmc, genParticleIndex) );
00744
00745 if (selectorFlag_) return selector_(trackingParticle);
00746
00747 return true;
00748 }
00749
00750
00751 int TrackingTruthProducer::setTrackingVertex(
00752 SimVertex const & simVertex,
00753 TrackingVertex & trackingVertex
00754 )
00755 {
00756 LorentzVector const & position = simVertex.position();
00757
00758
00759 for (std::size_t trackingVertexIndex = 0; trackingVertexIndex < trackingVertexes_->size(); ++trackingVertexIndex)
00760 {
00761
00762 double distance = (position - trackingVertexes_->at(trackingVertexIndex).position()).P();
00763
00764 if (distance <= distanceCut_)
00765 {
00766
00767 trackingVertexes_->at(trackingVertexIndex).addG4Vertex(simVertex);
00768
00769 return trackingVertexIndex;
00770 }
00771 }
00772
00773
00774 EncodedEventId simVertexEventId = simVertex.eventId();
00775
00776
00777 if (eventIdCounter_.find(simVertexEventId) == eventIdCounter_.end())
00778 eventIdCounter_[simVertexEventId] = 0;
00779
00780
00781 EncodedTruthId simVertexId = EncodedTruthId(simVertexEventId, eventIdCounter_[simVertexEventId]);
00782
00783
00784 bool inVolume = (position.Pt() < volumeRadius_ && std::abs(position.z()) < volumeZ_);
00785
00786
00787 trackingVertex = TrackingVertex(position, inVolume, simVertexId);
00788
00789
00790 addCloseGenVertexes(trackingVertex);
00791
00792
00793 trackingVertex.addG4Vertex(simVertex);
00794
00795
00796 eventIdCounter_[simVertexEventId]++;
00797
00798 return -1;
00799 }
00800
00801
00802 void TrackingTruthProducer::addCloseGenVertexes(TrackingVertex & trackingVertex)
00803 {
00804
00805 edm::Handle<edm::HepMCProduct> hepmc = (useMultipleHepMCLabels_) ? hepMCProducts_.at(trackingVertex.eventId().rawId()) : hepMCProducts_.at(0);
00806 const HepMC::GenEvent * genEvent = hepmc->GetEvent();
00807
00808
00809 Vector tvPosition(trackingVertex.position().x(), trackingVertex.position().y(), trackingVertex.position().z());
00810
00811
00812 for (
00813 HepMC::GenEvent::vertex_const_iterator iGenVertex = genEvent->vertices_begin();
00814 iGenVertex != genEvent->vertices_end();
00815 ++iGenVertex
00816 )
00817 {
00818
00819 HepMC::ThreeVector rawPosition = (*iGenVertex)->position();
00820
00821
00822 Vector genPosition(rawPosition.x()/10.0, rawPosition.y()/10.0, rawPosition.z()/10.0);
00823
00824
00825 double distance = sqrt( (tvPosition - genPosition).mag2() );
00826
00827 if (distance <= distanceCut_)
00828 trackingVertex.addGenVertex( GenVertexRef(hepmc, (*iGenVertex)->barcode()) );
00829 }
00830 }
00831
00832
00833 int TrackingTruthProducer::LayerFromDetid(const unsigned int & detid)
00834 {
00835 DetId detId = DetId(detid);
00836
00837 if ( detId.det() != DetId::Tracker ) return 0;
00838
00839 int layerNumber=0;
00840 unsigned int subdetId = static_cast<unsigned int>(detId.subdetId());
00841
00842 if ( subdetId == StripSubdetector::TIB)
00843 {
00844 TIBDetId tibid(detId.rawId());
00845 layerNumber = tibid.layer();
00846 }
00847 else if ( subdetId == StripSubdetector::TOB )
00848 {
00849 TOBDetId tobid(detId.rawId());
00850 layerNumber = tobid.layer();
00851 }
00852 else if ( subdetId == StripSubdetector::TID)
00853 {
00854 TIDDetId tidid(detId.rawId());
00855 layerNumber = tidid.wheel();
00856 }
00857 else if ( subdetId == StripSubdetector::TEC )
00858 {
00859 TECDetId tecid(detId.rawId());
00860 layerNumber = tecid.wheel();
00861 }
00862 else if ( subdetId == PixelSubdetector::PixelBarrel )
00863 {
00864 PXBDetId pxbid(detId.rawId());
00865 layerNumber = pxbid.layer();
00866 }
00867 else if ( subdetId == PixelSubdetector::PixelEndcap )
00868 {
00869 PXFDetId pxfid(detId.rawId());
00870 layerNumber = pxfid.disk();
00871 }
00872 else
00873 edm::LogVerbatim("TrackingTruthProducer") << "Unknown subdetid: " << subdetId;
00874
00875 return layerNumber;
00876 }
00877
00878 DEFINE_FWK_MODULE(TrackingTruthProducer);