CMS 3D CMS Logo

TrackingTruthProducer.cc

Go to the documentation of this file.
00001 #include "DataFormats/DetId/interface/DetId.h"
00002 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00003 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00004 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00005 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00006 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00007 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00008 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00009 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00010 
00011 #include "FWCore/Framework/interface/MakerMacros.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 
00014 #include "SimDataFormats/EncodedEventId/interface/EncodedEventId.h"
00015 
00016 #include "SimGeneral/TrackingAnalysis/interface/TrackingTruthProducer.h"
00017 
00018 
00019 using namespace edm;
00020 using namespace std;
00021 
00022 typedef edm::Ref<edm::HepMCProduct, HepMC::GenParticle > GenParticleRef;
00023 typedef edm::Ref<edm::HepMCProduct, HepMC::GenVertex >   GenVertexRef;
00024 typedef math::XYZTLorentzVectorD    LorentzVector;
00025 
00026 TrackingTruthProducer::TrackingTruthProducer(const edm::ParameterSet &conf) 
00027 {
00028   conf_ = conf;
00029   distanceCut_           = conf_.getParameter<double>("vertexDistanceCut");
00030   dataLabels_            = conf_.getParameter<vector<string> >("HepMCDataLabels");
00031   simHitLabel_           = conf_.getParameter<string>("simHitLabel");
00032   hitLabelsVector_       = conf_.getParameter<vector<string> >("TrackerHitLabels");
00033   volumeRadius_          = conf_.getParameter<double>("volumeRadius");
00034   volumeZ_               = conf_.getParameter<double>("volumeZ");
00035   discardOutVolume_      = conf_.getParameter<bool>("discardOutVolume");
00036   discardHitsFromDeltas_ = conf_.getParameter<bool>("DiscardHitsFromDeltas");
00037   mergedBremsstrahlung_  = conf_.getParameter<bool>("mergedBremsstrahlung");
00038   
00039   MessageCategory_       = "TrackingTruthProducer";
00040 
00041   edm::LogInfo (MessageCategory_) << "Setting up TrackingTruthProducer";
00042   edm::LogInfo (MessageCategory_) << "Vertex distance cut set to " << distanceCut_  << " mm";
00043   edm::LogInfo (MessageCategory_) << "Volume radius set to "       << volumeRadius_ << " mm";
00044   edm::LogInfo (MessageCategory_) << "Volume Z      set to "       << volumeZ_      << " mm";
00045   edm::LogInfo (MessageCategory_) << "Discard out of volume? "     << discardOutVolume_;
00046   edm::LogInfo (MessageCategory_) << "Discard Hits from Deltas? "  << discardHitsFromDeltas_;
00047 
00048   if (!mergedBremsstrahlung_)
00049   {
00050     produces<TrackingVertexCollection>();
00051     produces<TrackingParticleCollection>();
00052   }
00053   else
00054   {
00055     produces<TrackingVertexCollection>();
00056     produces<TrackingParticleCollection>();
00057     produces<TrackingVertexCollection>("MergedTrackTruth");
00058     produces<TrackingParticleCollection>("MergedTrackTruth");  
00059   }
00060 }
00061 
00062 void TrackingTruthProducer::produce(Event &event, const EventSetup &)
00063 {
00064 //  TimerStack timers;  // Don't need the timers now, left for example
00065 //  timers.push("TrackingTruth:Producer");
00066 //  timers.push("TrackingTruth:Setup");
00067 
00068   // Get HepMC out of event record
00069   edm::Handle<edm::HepMCProduct> hepMC;
00070   bool foundHepMC = false;
00071   for (vector<string>::const_iterator source = dataLabels_.begin(); source != dataLabels_.end(); ++source) 
00072   {
00073     foundHepMC = event.getByLabel(*source,hepMC);
00074     if (foundHepMC) 
00075     {
00076       edm::LogInfo (MessageCategory_) << "Using HepMC source " << *source;
00077       break;
00078     }
00079   }
00080 
00081   if (!foundHepMC)
00082   {
00083     edm::LogWarning (MessageCategory_) << "No HepMC source found";
00084     return;
00085   }
00086 
00087   const edm::HepMCProduct * mcp = hepMC.product();
00088 
00089   if (mcp == 0)
00090   {
00091     edm::LogWarning (MessageCategory_) << "Null HepMC pointer";
00092     return;
00093   }
00094   
00095   // New Templated CF
00096   // Grab all the PSimHit
00097   edm::Handle<CrossingFrame<PSimHit> > cf_simhit;
00098   std::vector<const CrossingFrame<PSimHit> *> cf_simhitvec;
00099   for(uint32_t i = 0; i< hitLabelsVector_.size();i++)
00100   {
00101     event.getByLabel("mix",hitLabelsVector_[i],cf_simhit);
00102     cf_simhitvec.push_back(cf_simhit.product());
00103   }
00104   std::auto_ptr<MixCollection<PSimHit> > hitCollection(new MixCollection<PSimHit>(cf_simhitvec));
00105 
00106   // Get all the simtracks from the crossing frame 
00107   edm::Handle<CrossingFrame<SimTrack> > cf_simtrack;
00108   event.getByLabel("mix", simHitLabel_, cf_simtrack);
00109   std::auto_ptr<MixCollection<SimTrack> > trackCollection(new MixCollection<SimTrack>(cf_simtrack.product()));
00110 
00111   // Get all the simvertex from the crossing frame 
00112   edm::Handle<CrossingFrame<SimVertex> > cf_simvertex;
00113   event.getByLabel("mix", simHitLabel_, cf_simvertex);
00114   std::auto_ptr<MixCollection<SimVertex> > vertexCollection(new MixCollection<SimVertex>(cf_simvertex.product()));
00115 
00116   // Create collections of things we will put in event
00117   auto_ptr<TrackingParticleCollection> tPC(new TrackingParticleCollection);
00118   auto_ptr<TrackingVertexCollection>   tVC(new TrackingVertexCollection  );
00119 
00120   // Get references before put so we can cross reference
00121   TrackingParticleRefProd refTPC = event.getRefBeforePut<TrackingParticleCollection>();
00122   TrackingVertexRefProd   refTVC = event.getRefBeforePut<TrackingVertexCollection>();
00123 
00124   //  timers.pop();
00125   
00126   // Create a one to many association between simtracks and hits
00127   simTrackHitsAssociator(hitCollection);
00128 
00129   // Assemble the tracking particles in function of the simtrack collection
00130   trackingParticleAssembler(tPC, trackCollection, hepMC);
00131   
00132   // Assemble the tracking vertexes including parents-daughters relations
00133   trackingVertexAssembler(tPC, tVC, trackCollection, vertexCollection, refTPC, refTVC, hepMC);
00134 
00135   edm::LogInfo(MessageCategory_) << "TrackingTruthProducer found " << tVC -> size()
00136                                  << " unique vertices and "        << tPC -> size() 
00137                                  << " tracks in the unmerged collection.";
00138 
00139   if (mergedBremsstrahlung_)
00140   {
00141         // Create collections of things we will put in event,
00142     auto_ptr<TrackingParticleCollection> mergedTPC(new TrackingParticleCollection);
00143     auto_ptr<TrackingVertexCollection>   mergedTVC(new TrackingVertexCollection  );
00144     
00145     // Get references before put so we can cross reference
00146     TrackingParticleRefProd refMergedTPC = event.getRefBeforePut<TrackingParticleCollection>("MergedTrackTruth");
00147     TrackingVertexRefProd   refMergedTVC = event.getRefBeforePut<TrackingVertexCollection>("MergedTrackTruth");
00148 
00149     // Merged Bremsstrahlung and copy the new collection into mergedTPC and mergedTVC
00150     mergeBremsstrahlung(tPC, tVC, mergedTPC, mergedTVC, refMergedTPC, refMergedTVC);  
00151 
00152     edm::LogInfo(MessageCategory_) << "TrackingTruthProducer found " << mergedTVC -> size()
00153                                    << " unique vertices and "        << mergedTPC -> size() 
00154                                    << " tracks in the merged collection.";
00155 
00156     // Put TrackingParticles and TrackingVertices in event
00157     event.put(mergedTPC,"MergedTrackTruth");
00158     event.put(mergedTVC,"MergedTrackTruth");
00159     event.put(tPC);
00160     event.put(tVC);
00161   }
00162   else
00163   {
00164     // Put TrackingParticles and TrackingVertices in event
00165     event.put(tPC);
00166     event.put(tVC);
00167   }
00168   
00169   //  timers.pop();
00170   //  timers.pop();
00171 }
00172 
00173 
00174 void TrackingTruthProducer::simTrackHitsAssociator(
00175   std::auto_ptr<MixCollection<PSimHit> > & hits
00176 )
00177 {
00178   simTrack_hit.clear();
00179   for (MixCollection<PSimHit>::MixItr hit = hits->begin(); hit != hits->end(); ++hit)
00180   {
00181     EncodedTruthId simTrackId = EncodedTruthId(hit->eventId(),hit->trackId());
00182     simTrack_hit.insert(make_pair(simTrackId,*hit));
00183   }
00184 }
00185 
00186 
00187 void TrackingTruthProducer::trackingParticleAssembler(
00188   auto_ptr<TrackingParticleCollection> & tPC,
00189   auto_ptr<MixCollection<SimTrack> > & tracks,
00190   Handle<edm::HepMCProduct> const & hepMC
00191 )
00192 {
00193   simTrack_sourceV.clear();
00194   simTrack_tP.clear();
00195   
00196   const HepMC::GenEvent * genEvent = hepMC->GetEvent();
00197 
00198   for (MixCollection<SimTrack>::MixItr itP = tracks->begin(); itP != tracks->end(); ++itP)
00199   {
00200     int                           q = (int)(itP->charge()); // Check this
00201     const LorentzVector theMomentum = itP->momentum();
00202     unsigned int         simtrackId = itP->trackId();
00203     int                     genPart = itP->genpartIndex(); // The HepMC particle number
00204     int                     genVert = itP->vertIndex();    // The SimVertex #
00205     int                       pdgId = itP->type();
00206     int                      status = -99;
00207 
00208     EncodedEventId trackEventId     = itP->eventId();
00209     EncodedTruthId      trackId     = EncodedTruthId(trackEventId,simtrackId);
00210 
00211     bool signalEvent = (trackEventId.event() == 0 && trackEventId.bunchCrossing() == 0);
00212 
00213     double  time = 0;
00214 
00215     const HepMC::GenParticle * gp = 0;
00216 
00217     if (genPart >= 0 && signalEvent)
00218     {
00219       gp = genEvent->barcode_to_particle(genPart);  // Pointer to the generating particle.
00220       if (gp != 0)
00221       {
00222         status = gp->status();
00223         pdgId  = gp->pdg_id();
00224       }
00225     }
00226 
00227     math::XYZPoint theVertex;
00228 
00229     if (genVert >= 0)
00230     { // Add to useful maps
00231       EncodedTruthId vertexId = EncodedTruthId(trackEventId,genVert);
00232       simTrack_sourceV.insert(make_pair(trackId,vertexId));
00233     }
00234 
00235     TrackingParticle tp(q, theMomentum, theVertex, time, pdgId, status, trackEventId);
00236 
00237     // Counting the TP hits using the layers (as in ORCA).
00238     // Does seem to find less hits. maybe b/c layer is a number now, not a pointer
00239     int totsimhit = 0;
00240     int oldlay = 0;
00241     int newlay = 0;
00242     int olddet = 0;
00243     int newdet = 0;
00244 
00245     // Using simTrack_hit map makes this very fast
00246     //now check the process ID
00247     bool checkProc = true;
00248     unsigned short procType = 0;
00249     int partType = 0;
00250     int hitcount = 0;
00251      
00252     for (
00253       multimap<EncodedTruthId,PSimHit>::const_iterator iHit = simTrack_hit.lower_bound(trackId);
00254           iHit != simTrack_hit.upper_bound(trackId); 
00255           ++iHit
00256         ) 
00257         {
00258       PSimHit hit = iHit->second;
00259       hitcount++;
00260       
00261       if(checkProc)
00262       {
00263             procType = hit.processType();
00264             partType = hit.particleType();
00265             checkProc = false; //check only the procType of the first hit
00266             //std::cout << "First Hit (proc, part) = " << procType << ", " << partType << std::endl;
00267       }
00268 
00269       //Check for delta and interaction products discards
00270       //std::cout << hitcount << " Hit (proc, part) = " << hit.processType() << ", " << hit.particleType() << std::endl;
00271       if(procType == hit.processType() && partType == hit.particleType() && pdgId == hit.particleType() )
00272       {
00273             //std::cout << "PASSED" << std::endl;
00274         tp.addPSimHit(hit);
00275 
00276         unsigned int detid = hit.detUnitId();
00277         DetId detId = DetId(detid);
00278         oldlay = newlay;
00279         olddet = newdet;
00280         newlay = LayerFromDetid(detid);
00281         newdet = detId.subdetId();
00282 
00283             // Count hits using layers for glued detectors (newlay !=0 excludes Muon layers set to 0 by LayerFromDetid)
00284 
00285         if ( (oldlay != newlay || (oldlay==newlay && olddet!=newdet) ) && newlay!=0 )
00286             {
00287               totsimhit++;
00288         }
00289       }
00290     }
00291 
00292     tp.setMatchedHit(totsimhit);
00293     tp.addG4Track(*itP);
00294 
00295     if (genPart >= 0 && signalEvent) {
00296       tp.addGenParticle(GenParticleRef(hepMC,genPart));
00297     }
00298 
00299     // Add indices to map and add to collection
00300     simTrack_tP.insert(make_pair(trackId,tPC->size()));
00301     tPC->push_back(tp);
00302   }
00303 }
00304 
00305 
00306 void TrackingTruthProducer::trackingVertexAssembler(
00307   auto_ptr<TrackingParticleCollection> & tPC,
00308   auto_ptr<TrackingVertexCollection> & tVC,
00309   auto_ptr<MixCollection<SimTrack> > & tracks,  
00310   auto_ptr<MixCollection<SimVertex> > & vertexes,
00311   TrackingParticleRefProd & refTPC,
00312   TrackingVertexRefProd & refTVC,
00313   Handle<edm::HepMCProduct> const & hepMC
00314 )
00315 {
00316 
00317   const HepMC::GenEvent * genEvent = hepMC->GetEvent();
00318 
00319   // Find and loop over EmbdSimVertex vertices
00320   
00321   int vertexIndex = 0;        // Needed for
00322   int oldTrigger = -1;        // renumbering
00323   int oldBX      = -999999;   // of vertices
00324   
00325   for (MixCollection<SimVertex>::MixItr itV = vertexes->begin(); itV != vertexes->end(); ++itV)
00326   {
00327     // LorentzVector position = itV -> position();  // Get position of ESV
00328     LorentzVector position(itV->position().x(),itV->position().y(),itV->position().z(),itV->position().t());
00329 
00330     bool inVolume = (position.Pt() < volumeRadius_ && abs(position.z()) < volumeZ_); // In or out of Tracker
00331 
00332     if (!inVolume && discardOutVolume_) { continue; }        // Skip if desired
00333 
00334     EncodedEventId vertEvtId = itV -> eventId();
00335 
00336     // Begin renumbering vertices if we move from signal to pileup or change bunch crossings
00337     if (oldTrigger !=  itV.getTrigger() || oldBX !=  vertEvtId.bunchCrossing())
00338     {
00339       vertexIndex = 0;
00340       oldTrigger =  itV.getTrigger();
00341       oldBX =  vertEvtId.bunchCrossing();
00342     }
00343 
00344     EncodedTruthId vertexId  = EncodedTruthId(vertEvtId,vertexIndex);
00345 
00346     // Figure out the barcode of the HepMC Vertex if there is one by
00347     // getting incoming SimTtrack (if any), finding corresponding HepMC track and
00348     // then decay (HepMC) vertex of that track.  HepMC data only exists for signal sub-event
00349 
00350     int vertexBarcode = 0;
00351     unsigned int vtxParent = itV -> parentIndex();
00352     if (vtxParent >= 0 && itV.getTrigger() ) 
00353     {
00354       for (MixCollection<SimTrack>::MixItr itP = tracks->begin(); itP != tracks->end(); ++itP)
00355       {
00356         if (vtxParent==itP->trackId() && itP->eventId() == vertEvtId)
00357         {
00358           int parentBC = itP->genpartIndex();
00359           HepMC::GenParticle *parentParticle = genEvent -> barcode_to_particle(parentBC);
00360           if (parentParticle != 0) 
00361           {
00362             HepMC::GenVertex * hmpv = parentParticle -> end_vertex();
00363             if (hmpv != 0) {
00364               vertexBarcode = hmpv  -> barcode();
00365             }
00366           }
00367           break;
00368         }
00369       }
00370     }
00371 
00372     // Find closest vertex to this one in same sub-event, save in nearestVertex
00373     int indexTV = 0;
00374     double closest = 9e99;
00375     TrackingVertexCollection::iterator nearestVertex;
00376 
00377     int tmpTV = 0;
00378     for (TrackingVertexCollection::iterator iTrkVtx = tVC -> begin(); iTrkVtx != tVC ->end(); ++iTrkVtx, ++tmpTV)
00379     {
00380       double distance = (iTrkVtx -> position() - position).P();
00381       if (distance <= closest && vertEvtId == iTrkVtx -> eventId())
00382       { // flag which one so we can associate them
00383         closest = distance;
00384         nearestVertex = iTrkVtx;
00385         indexTV = tmpTV;
00386       }
00387     }
00388 
00389     // If outside cutoff, create another TrackingVertex, set nearestVertex to it
00390     if (closest > distanceCut_)
00391     {
00392       indexTV = tVC -> size();
00393       tVC -> push_back(TrackingVertex(position,inVolume,vertEvtId));
00394       nearestVertex = --(tVC -> end());  // Last entry of vector
00395     }
00396 
00397     // Add data to closest vertex
00398 
00399     (*nearestVertex).addG4Vertex(*itV); // Add G4 vertex
00400     if (vertexBarcode != 0)
00401     {
00402       (*nearestVertex).addGenVertex(GenVertexRef(hepMC,vertexBarcode)); // Add HepMC vertex
00403     }
00404 
00405     // Identify and add child tracks
00406     for (std::map<EncodedTruthId,EncodedTruthId>::iterator mapIndex = simTrack_sourceV.begin(); mapIndex != simTrack_sourceV.end(); ++mapIndex)
00407     {
00408       EncodedTruthId mapTrackId  = mapIndex -> first;
00409       EncodedTruthId mapVertexId = mapIndex -> second;
00410       if (mapVertexId == vertexId)
00411       {
00412         if (simTrack_tP.count(mapTrackId))
00413         {
00414           int indexTP = simTrack_tP[mapTrackId];
00415           (*nearestVertex).addDaughterTrack(TrackingParticleRef(refTPC,indexTP));
00416           (tPC->at(indexTP)).setParentVertex(TrackingVertexRef(refTVC,indexTV));
00417           const LorentzVector  &v = (*nearestVertex).position();
00418 
00419           math::XYZPoint xyz = math::XYZPoint(v.x(), v.y(), v.z());
00420           double t = v.t();
00421           (tPC->at(indexTP)).setVertex(xyz,t);
00422         }
00423       }
00424     }
00425 
00426     // Identify and add parent tracks
00427     if (vtxParent > 0) 
00428     {
00429       EncodedTruthId trackId =  EncodedTruthId(vertEvtId,vtxParent);
00430       if (simTrack_tP.count(trackId) > 0) 
00431       {
00432         int indexTP = simTrack_tP[trackId];
00433         (tPC->at(indexTP)).addDecayVertex(TrackingVertexRef(refTVC,indexTV));
00434         (*nearestVertex).addParentTrack(TrackingParticleRef(refTPC,indexTP));
00435       }
00436     }
00437     ++vertexIndex;
00438   } // Loop on MixCollection<SimVertex>
00439 
00440   // Find HepMC vertices, put them in a close TrackingVertex (this could conceivably add the same GenVertex to multiple TrackingVertices)
00441   for (HepMC::GenEvent::vertex_const_iterator genVIt = genEvent->vertices_begin(); genVIt != genEvent->vertices_end(); ++genVIt) 
00442   {
00443     HepMC::ThreeVector rawPos = (**genVIt).position();
00444     // Convert to cm
00445     math::XYZPoint genPos = math::XYZPoint(rawPos.x()/10.0,rawPos.y()/10.0,rawPos.z()/10.0);
00446     for (TrackingVertexCollection::iterator iTrkVtx = tVC -> begin(); iTrkVtx != tVC ->end(); ++iTrkVtx)
00447     {
00448       rawPos = iTrkVtx->position();
00449       math::XYZPoint simPos = math::XYZPoint(rawPos.x(),rawPos.y(),rawPos.z());
00450       double distance = sqrt((simPos-genPos).mag2());
00451       if (distance <= distanceCut_)
00452       {
00453         TrackingVertex::genv_iterator tvGenVIt;
00454         for (tvGenVIt = iTrkVtx->genVertices_begin(); tvGenVIt != iTrkVtx->genVertices_end(); ++tvGenVIt)
00455         {
00456           if ((**genVIt).barcode()  == (**tvGenVIt).barcode())
00457           {
00458             break;
00459           }
00460         }
00461         if (tvGenVIt== iTrkVtx->genVertices_end() )
00462         {
00463           iTrkVtx->addGenVertex(GenVertexRef(hepMC,(**genVIt).barcode())); // Add HepMC vertex
00464         }
00465       }
00466     }
00467   }
00468 }
00469 
00470 
00471 
00472 void TrackingTruthProducer::mergeBremsstrahlung(
00473   auto_ptr<TrackingParticleCollection> & tPC,
00474   auto_ptr<TrackingVertexCollection>   & tVC,
00475   auto_ptr<TrackingParticleCollection> & mergedTPC,
00476   auto_ptr<TrackingVertexCollection>   & mergedTVC,
00477   TrackingParticleRefProd & refMergedTPC,
00478   TrackingVertexRefProd & refMergedTVC
00479 )
00480 {     
00481   std::set<uint> excludedTV, excludedTP;
00482   
00483   uint index = 0;
00484   
00485   // Merge Bremsstrahlung vertexes
00486   for (TrackingVertexCollection::iterator iVC = tVC->begin(); iVC != tVC->end(); ++iVC, ++index)
00487   {
00488     // Check Bremsstrahlung vertex
00489     if ( isBremsstrahlungVertex(*iVC, tPC) )
00490     {
00491       // Get a pointer to the source track (A Ref<> cannot be use with a product!)      
00492       TrackingParticle * track = &tPC->at(iVC->sourceTracks_begin()->key());
00493       // Get a Ref<> to the source track
00494       TrackingParticleRef trackRef = *iVC->sourceTracks_begin();
00495       // Pointer to electron daughter
00496       TrackingParticle * daughter = 0;
00497       // Ref<> to electron daughter
00498       TrackingParticleRef daughterRef;
00499 
00500       // Select the electron daughter and veto the photon
00501       for (TrackingVertex::tp_iterator idaughter = iVC->daughterTracks_begin(); idaughter != iVC->daughterTracks_end(); ++idaughter)
00502       {
00503         TrackingParticle * pointer = &tPC->at(idaughter->key());
00504         if ( abs( pointer->pdgId() ) == 11 )
00505         {
00506           // Set pointer to the electron daughter
00507           daughter = pointer;
00508           // Set Ref<> to the electron daughter
00509           daughterRef = *idaughter;
00510         }
00511         else if ( pointer->pdgId() == 22 )
00512         {
00513           // Remove reference to the voted photon       
00514           for ( TrackingParticle::tv_iterator idecay = pointer->decayVertices_begin(); idecay != pointer->decayVertices_end(); ++idecay )
00515           {
00516             // Get a reference to decay vertex
00517             TrackingVertex * vertex = &tVC->at( idecay->key() );
00518             // Copy all the source tracks from of the decay vertex 
00519             TrackingParticleRefVector sources( vertex->sourceTracks() );    
00520             // Clear the source track references
00521             vertex->clearParentTracks();
00522             // Add the new source tracks by excluding the one with the segment merged 
00523             for(TrackingVertex::tp_iterator isource = sources.begin(); isource != sources.end(); ++isource)
00524               if (*isource != *idaughter)
00525                 vertex->addParentTrack(*isource);
00526           }
00527           excludedTP.insert( idaughter->key() );          
00528         }
00529       }
00530 
00531       // Add the electron segments from the electron daughter
00532       // track must not be the same particle as daughter
00533       if(track != daughter)
00534         for (TrackingParticle::g4t_iterator isegment = daughter->g4Track_begin(); isegment != daughter->g4Track_end(); ++isegment) {
00535           track->addG4Track(*isegment);
00536         }
00537       
00538       // Copy all the simhits to the new track  
00539       for (std::vector<PSimHit>::const_iterator ihit = daughter->pSimHit_begin(); ihit != daughter->pSimHit_end(); ++ihit)
00540         track->addPSimHit(*ihit);
00541 
00542       // Clear the decay vertex list      
00543       track->clearDecayVertices();
00544 
00545       // Redirect all the decay source vertexes to those in the electron daughter  
00546       for (TrackingParticle::tv_iterator idecay = daughter->decayVertices_begin(); idecay != daughter->decayVertices_end(); ++idecay)
00547       { 
00548         // Add the vertexes to the decay list of the source particles
00549         track->addDecayVertex(*idecay);
00550         // Get a reference to decay vertex
00551         TrackingVertex * vertex = &tVC->at( idecay->key() );
00552         // Copy all the source tracks from of the decay vertex 
00553         TrackingParticleRefVector sources( vertex->sourceTracks() );
00554         // Clear the source track references
00555         vertex->clearParentTracks();
00556         // Add the new source tracks by excluding the one with the segment merged 
00557         for(TrackingVertex::tp_iterator isource = sources.begin(); isource != sources.end(); ++isource)
00558           if (*isource != daughterRef) 
00559             vertex->addParentTrack(*isource);
00560         // Add the track reference to the list of sources 
00561         vertex->addParentTrack(trackRef);
00562       } 
00563               
00564       // Adding the vertex to the exlusion list
00565       excludedTV.insert(index);
00566             
00567       // Adding the electron segment tp into the exlusion list
00568       excludedTP.insert( daughterRef.key() );
00569     }
00570   }     
00571 
00572   edm::LogInfo(MessageCategory_) << "Generating the merged collection." << std::endl;
00573         
00574   // Reserved the same amount of memory for the merged collections      
00575   mergedTPC->reserve(tPC->size());
00576   mergedTVC->reserve(tVC->size());
00577 
00578   index = 0;
00579   map<uint, uint> vertexMap;
00580 
00581   // Copy non-excluded vertices discarding parent & child tracks 
00582   for (TrackingVertexCollection::const_iterator iVC = tVC->begin(); iVC != tVC->end(); ++iVC, ++index)
00583   {
00584     if ( excludedTV.find(index) != excludedTV.end() ) continue;
00585     // Save the new location of the non excluded vertexes (take in consideration those were removed) 
00586     vertexMap.insert( make_pair(index, mergedTVC->size()) );
00587     // Copy those vertexes are not excluded
00588     TrackingVertex newVertex = (*iVC);
00589     newVertex.clearDaughterTracks();
00590     newVertex.clearParentTracks();
00591     mergedTVC->push_back(newVertex);
00592   }
00593   
00594   index = 0;
00595   
00596   // Copy and cross reference the non-excluded tp to the merged collection
00597   for (TrackingParticleCollection::const_iterator iTP = tPC->begin(); iTP != tPC->end(); ++iTP, ++index)
00598   {
00599         if ( excludedTP.find(index) != excludedTP.end() ) continue;
00600     
00601     TrackingVertexRef       sourceV = iTP->parentVertex();
00602     TrackingVertexRefVector decayVs = iTP->decayVertices();
00603     TrackingParticle newTrack = *iTP;
00604  
00605     newTrack.clearParentVertex();
00606     newTrack.clearDecayVertices();
00607 
00608     // Set vertex indices for new vertex product and track references in those vertices
00609     
00610     // Index of parent vertex in vertex container
00611     uint parentIndex = vertexMap[sourceV.key()];
00612     // Index of this track in track container
00613     uint tIndex      = mergedTPC->size();
00614 
00615     // Add vertex to track
00616     newTrack.setParentVertex(TrackingVertexRef(refMergedTVC,parentIndex));
00617     // Add track to vertex
00618     (mergedTVC->at(parentIndex)).addDaughterTrack(TrackingParticleRef(refMergedTPC,tIndex));
00619     
00620     for (TrackingVertexRefVector::const_iterator iDecayV = decayVs.begin(); iDecayV != decayVs.end(); ++iDecayV)
00621     {
00622        // Index of decay vertex in vertex container
00623       uint daughterIndex = vertexMap[iDecayV->key()];
00624       // Add vertex to track
00625       newTrack.addDecayVertex(TrackingVertexRef(refMergedTVC,daughterIndex));
00626       // Add track to vertex
00627       (mergedTVC->at(daughterIndex)).addParentTrack(TrackingParticleRef(refMergedTPC,tIndex));
00628     }
00629     
00630     mergedTPC->push_back(newTrack);
00631   }
00632 }
00633  
00634 
00635 bool TrackingTruthProducer::isBremsstrahlungVertex(
00636   TrackingVertex const & vertex,
00637   auto_ptr<TrackingParticleCollection> & tPC
00638 )
00639 {
00640   const TrackingParticleRefVector parents(vertex.sourceTracks());
00641       
00642   // Check for the basic parent conditions
00643   if ( parents.size() != 1)
00644     return false;
00645 
00646   // Check for the parent particle is a |electron| (electron or positron)
00647   if ( abs( tPC->at(parents.begin()->key()).pdgId() ) != 11 ) 
00648     return false;
00649     
00650   int nElectrons = 0;
00651   int nPhotons = 0;
00652   int nOthers = 0;  
00653 
00654   // Loop over the daughter particles and counts the number of |electrons|, photons or others        
00655   for ( TrackingVertex::tp_iterator it = vertex.daughterTracks_begin(); it != vertex.daughterTracks_end(); ++it )
00656   {
00657     // Stronger rejection for looping particles
00658     if ( parents[0] == *it )
00659       return false;
00660 
00661     if ( abs( tPC->at(it->key()).pdgId() ) == 11 )
00662       nElectrons++;
00663     else if ( tPC->at(it->key()).pdgId() == 22 )
00664       nPhotons++;
00665     else
00666       nOthers++;
00667   }
00668 
00669   // Condition to be a Bremsstrahlung Vertex
00670   if (nElectrons == 1 && nPhotons == 1 && nOthers == 0) 
00671     return true;
00672   
00673   return false;   
00674 }
00675 
00676 
00677 int TrackingTruthProducer::LayerFromDetid(const unsigned int& detid )
00678 {
00679   DetId detId = DetId(detid);
00680   int layerNumber=0;
00681   
00682   // needed to check only the Tracker layers
00683   if( detId.det() != DetId::Tracker )
00684     return layerNumber;
00685   
00686   // Tracker layers
00687   unsigned int subdetId = static_cast<unsigned int>(detId.subdetId());
00688   if ( subdetId == StripSubdetector::TIB )
00689     {
00690       TIBDetId tibid(detId.rawId());
00691       layerNumber = tibid.layer();
00692     }
00693   else if ( subdetId ==  StripSubdetector::TOB )
00694     {
00695       TOBDetId tobid(detId.rawId());
00696       layerNumber = tobid.layer();
00697     }
00698   else if ( subdetId ==  StripSubdetector::TID )
00699     {
00700       TIDDetId tidid(detId.rawId());
00701       layerNumber = tidid.wheel();
00702     }
00703   else if ( subdetId ==  StripSubdetector::TEC )
00704     {
00705       TECDetId tecid(detId.rawId());
00706       layerNumber = tecid.wheel();
00707     }
00708   else if ( subdetId ==  PixelSubdetector::PixelBarrel )
00709     {
00710       PXBDetId pxbid(detId.rawId());
00711       layerNumber = pxbid.layer();
00712     }
00713   else if ( subdetId ==  PixelSubdetector::PixelEndcap )
00714     {
00715       PXFDetId pxfid(detId.rawId());
00716       layerNumber = pxfid.disk();
00717     }
00718   else
00719     edm::LogVerbatim("TrackingTruthProducer") << "Unknown subdetid: " <<  subdetId;
00720 
00721   return layerNumber;
00722 }
00723 
00724 //DEFINE_FWK_MODULE(TrackingTruthProducer);

Generated on Tue Jun 9 17:47:29 2009 for CMSSW by  doxygen 1.5.4