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