CMS 3D CMS Logo

FastTrackMerger.cc

Go to the documentation of this file.
00001 #include <memory>
00002 
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/Framework/interface/EventSetup.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 
00008 #include "DataFormats/Common/interface/Handle.h"
00009 #include "DataFormats/Common/interface/OwnVector.h"
00010 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSRecHit2DCollection.h" 
00011 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSMatchedRecHit2DCollection.h" 
00012 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00013 #include "DataFormats/TrackReco/interface/Track.h"
00014 #include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
00015 
00016 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00017 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00018 
00019 #include "FastSimulation/Tracking/plugins/FastTrackMerger.h"
00020 
00021 #include <vector>
00022 #include <map>
00023 //
00024 
00025 //for debug only 
00026 //#define FAMOS_DEBUG
00027 
00028 FastTrackMerger::FastTrackMerger(const edm::ParameterSet& conf) 
00029 {  
00030 #ifdef FAMOS_DEBUG
00031   std::cout << "FastTrackMerger created" << std::endl;
00032 #endif
00033 
00034   // The main product is a track collection, and all extras
00035   produces<reco::TrackCollection>();
00036   
00037   // The name of the track producers to merge
00038   trackProducers = conf.getParameter<std::vector<edm::InputTag> >("TrackProducers");
00039 
00040   // The name of the track producers to remove
00041   std::vector<edm::InputTag> defaultRemove;
00042   removeTrackProducers = 
00043     conf.getUntrackedParameter<std::vector<edm::InputTag> >("RemoveTrackProducers",defaultRemove);
00044 
00045   // Only the tracks!
00046   tracksOnly = conf.getUntrackedParameter<bool>("SaveTracksOnly",false);
00047 
00048   // optional pT cut
00049   double pTMin = conf.getUntrackedParameter<bool>("pTMin",0.);
00050   pTMin2 = pTMin*pTMin;
00051 
00052   // optional nHit cut
00053   minHits = conf.getUntrackedParameter<unsigned>("minHits",0);
00054 
00055   // optional track quality saving
00056   promoteQuality = conf.getUntrackedParameter<bool>("promoteTrackQuality",false);
00057   qualityStr = conf.getUntrackedParameter<std::string>("newQuality","");
00058 
00059   if ( !tracksOnly ) { 
00060     produces<reco::TrackExtraCollection>();
00061     produces<TrackingRecHitCollection>();
00062     produces<std::vector<Trajectory> >();
00063     produces<TrajTrackAssociationCollection>();
00064   }
00065 }
00066 
00067   
00068 // Functions that gets called by framework every event
00069 void 
00070 FastTrackMerger::produce(edm::Event& e, const edm::EventSetup& es) {        
00071 
00072 #ifdef FAMOS_DEBUG
00073   std::cout << "################################################################" << std::endl;
00074   std::cout << " FastTrackMerger produce init " << std::endl;
00075 #endif
00076 
00077   // The produced objects
00078   std::auto_ptr<reco::TrackCollection> recoTracks(new reco::TrackCollection);
00079   std::auto_ptr<reco::TrackExtraCollection> recoTrackExtras(new reco::TrackExtraCollection);
00080   std::auto_ptr<TrackingRecHitCollection> recoHits(new TrackingRecHitCollection);
00081   std::auto_ptr<std::vector<Trajectory> > recoTrajectories(new std::vector<Trajectory>);
00082   std::auto_ptr<TrajTrackAssociationCollection> recoTrajTrackMap(new TrajTrackAssociationCollection());
00083 
00084   // No seed -> output an empty track collection
00085   if(trackProducers.size() == 0) {
00086     e.put(recoTracks);
00087     if ( !tracksOnly ) { 
00088       e.put(recoTrackExtras);
00089       e.put(recoHits);
00090       e.put(recoTrajectories);
00091       e.put(recoTrajTrackMap);
00092     }
00093     return;
00094   }
00095 
00096   // The quality to be set
00097   reco::TrackBase::TrackQuality qualityToSet;
00098   if (qualityStr != "")
00099     qualityToSet = reco::TrackBase::qualityByName(qualityStr);
00100   else 
00101     qualityToSet = reco::TrackBase::undefQuality;
00102 
00103   // The input track collection handle
00104   edm::Handle<reco::TrackCollection> theTrackCollection;
00105 
00106   // First, the tracks to be removed
00107   std::set<unsigned> removeTracks;
00108   for ( unsigned aProducer=0; aProducer<removeTrackProducers.size(); ++aProducer ) { 
00109     bool isTrackCollection = e.getByLabel(removeTrackProducers[aProducer],theTrackCollection); 
00110     if (!isTrackCollection) continue;
00111     reco::TrackCollection::const_iterator aTrack = theTrackCollection->begin();
00112     reco::TrackCollection::const_iterator lastTrack = theTrackCollection->end();
00113     for ( ; aTrack!=lastTrack; ++aTrack ) {
00114       // Get the simtrack Id
00115       int recoTrackId = findId(*aTrack);
00116       if ( recoTrackId < 0 ) continue;
00117       // Remove the track if requested
00118       if ( removeTracks.find((unsigned)recoTrackId) != removeTracks.end() ) continue;
00119       removeTracks.insert((unsigned)recoTrackId);
00120     }      
00121   }
00122   
00123   // Then the tracks to be added
00124   std::set<unsigned> alreadyAddedTracks;
00125   
00126   // Loop on the track producers to be merged
00127   for ( unsigned aProducer=0; aProducer<trackProducers.size(); ++aProducer ) { 
00128     
00129     bool isTrackCollection = e.getByLabel(trackProducers[aProducer],theTrackCollection); 
00130     if ( ! isTrackCollection ) { 
00131 #ifdef FAMOS_DEBUG
00132       std::cout << "***FastTrackMerger*** Warning! The track collection " 
00133                 << trackProducers[aProducer].encode() 
00134                 << " does not exist." << std::endl;
00135 #endif
00136       continue;
00137     }
00138 
00139 #ifdef FAMOS_DEBUG
00140     std::cout << "***FastTrackMerger*** of track collection " 
00141               << trackProducers[aProducer].encode() 
00142               << " with " << theTrackCollection->size() 
00143               << " tracks to be copied"
00144               << std::endl;
00145 #endif
00146     reco::TrackCollection::const_iterator aTrack = theTrackCollection->begin();
00147     reco::TrackCollection::const_iterator lastTrack = theTrackCollection->end();
00148 
00149     // Only tracks are to be copied -> loop on the track collection and copy
00150     if ( tracksOnly ) { 
00151 
00152       // edm:: Handle<reco::TrackExtraCollection > theTrackExtraCollection;
00153       // bool isTrackExtraCollection = e.getByLabel(trackProducers[aProducer],theTrackExtraCollection); 
00154       bool index = 0;
00155       for ( ; aTrack!=lastTrack; ++aTrack,++index ) {
00156 
00157         // Find the track id
00158         int recoTrackId = findId(*aTrack);
00159         if ( recoTrackId < 0 ) continue;
00160         
00161         // Ignore tracks to be removed or tracks already copied
00162         std::set<unsigned>::iterator iR = removeTracks.find((unsigned)recoTrackId);
00163 #ifdef FAMOS_DEBUG
00164         if( iR != removeTracks.end() ) std::cout << recoTrackId << "(REMOVED) ";
00165 #endif
00166         if( iR != removeTracks.end() ) continue;
00167         
00168         // Ignore tracks already copied
00169         std::set<unsigned>::iterator iA = alreadyAddedTracks.find((unsigned)recoTrackId);
00170 #ifdef FAMOS_DEBUG
00171         if( iA != alreadyAddedTracks.end() ) std::cout << recoTrackId << "(ALREADY ADDED) ";
00172 #endif
00173         if( iA != alreadyAddedTracks.end() ) continue;
00174         
00175 #ifdef FAMOS_DEBUG
00176         std::cout << recoTrackId << " ";
00177 #endif
00178 
00179         // Ignore tracks with too small a pT
00180         if ( aTrack->innerMomentum().Perp2() < pTMin2 ) continue;
00181         
00182         // Ignore tracks with too small a pT
00183         if ( aTrack->recHitsSize() < minHits ) continue;
00184         
00185         // A copy of the track + save the transient reference to the track extra reference
00186         reco::Track aRecoTrack(*aTrack);
00187         // const reco::TrackExtraRef theTrackExtraRef(*theTrackExtraCollection,index);
00188         // if ( isTrackExtraCollection ) aRecoTrack.setExtra(theTrackExtraRef);
00189         recoTracks->push_back(aRecoTrack);
00190         // Save the quality if requested
00191         if (promoteQuality) recoTracks->back().setQuality(qualityToSet);        
00192         
00193       }
00194       
00195 
00196     // All extras are to be copied too -> loop on the Trajectory/Track map association 
00197     } else { 
00198 
00199       edm:: Handle<std::vector<Trajectory> > theTrajectoryCollection;
00200       edm::Handle<TrajTrackAssociationCollection> theAssoMap;  
00201 
00202       // Count the number of hits and reserve appropriate memory
00203       unsigned nRecoHits = 0;
00204       for ( ; aTrack!=lastTrack; ++aTrack ) nRecoHits+= aTrack->recHitsSize();
00205       recoHits->reserve(nRecoHits); // This is to save some time at push_back.
00206       
00207       e.getByLabel(trackProducers[aProducer],theTrajectoryCollection);
00208       e.getByLabel(trackProducers[aProducer],theAssoMap);
00209       
00210       // The track collection iterators.
00211       TrajTrackAssociationCollection::const_iterator anAssociation;  
00212       TrajTrackAssociationCollection::const_iterator lastAssociation;
00213       anAssociation = theAssoMap->begin();
00214       lastAssociation = theAssoMap->end();
00215 #ifdef FAMOS_DEBUG
00216       std::cout << "List of tracks to be copied " << std::endl;
00217 #endif
00218       // Build the map of correspondance between reco tracks and sim tracks
00219       for ( ; anAssociation != lastAssociation; ++anAssociation ) { 
00220         edm::Ref<std::vector<Trajectory> > aTrajectoryRef = anAssociation->key;
00221         reco::TrackRef aTrackRef = anAssociation->val;
00222         // Find the track id
00223         int recoTrackId = findId(*aTrackRef);
00224         if ( recoTrackId < 0 ) continue;
00225         
00226         // Ignore tracks to be removed or tracks already copied
00227         std::set<unsigned>::iterator iR = removeTracks.find((unsigned)recoTrackId);
00228 #ifdef FAMOS_DEBUG
00229         if( iR != removeTracks.end() ) std::cout << recoTrackId << "(REMOVED) ";
00230 #endif
00231         if( iR != removeTracks.end() ) continue;
00232         
00233         // Ignore tracks already copied
00234         std::set<unsigned>::iterator iA = alreadyAddedTracks.find((unsigned)recoTrackId);
00235 #ifdef FAMOS_DEBUG
00236         if( iA != alreadyAddedTracks.end() ) std::cout << recoTrackId << "(ALREADY ADDED) ";
00237 #endif
00238         if( iA != alreadyAddedTracks.end() ) continue;
00239         
00240 #ifdef FAMOS_DEBUG
00241         std::cout << recoTrackId << " ";
00242 #endif
00243         
00244         // Ignore tracks with too small a pT
00245         if ( aTrackRef->innerMomentum().Perp2() < pTMin2 ) continue;
00246         
00247         // Ignore tracks with too few hits
00248         if ( aTrackRef->recHitsSize() < minHits ) continue;
00249         
00250         // A copy of the track
00251         reco::Track aRecoTrack(*aTrackRef);
00252         recoTracks->push_back(aRecoTrack);      
00253         // Save the quality if requested
00254         if (promoteQuality) recoTracks->back().setQuality(qualityToSet);        
00255         // A copy of the hits
00256         unsigned nh = aRecoTrack.recHitsSize();
00257         for ( unsigned ih=0; ih<nh; ++ih ) {
00258           TrackingRecHit *hit = aRecoTrack.recHit(ih)->clone();
00259           recoHits->push_back(hit);
00260         }
00261         
00262         // A copy of the trajectories
00263         recoTrajectories->push_back(*aTrajectoryRef);
00264         
00265       }
00266 #ifdef FAMOS_DEBUG
00267       std::cout << std::endl;
00268 #endif
00269     }
00270 }
00271     
00272     // Save the track candidates in the event
00273 #ifdef FAMOS_DEBUG
00274   std::cout << "Saving " 
00275             << recoTracks->size() << " reco::Tracks " << std::endl;
00276 #endif
00277   
00278   if ( tracksOnly ) { 
00279     // Save only the tracks (with transient reference to track extras)
00280     e.put(recoTracks);
00281 
00282   } else { 
00283     // Save the tracking recHits
00284     edm::OrphanHandle <TrackingRecHitCollection> theRecoHits = e.put(recoHits );
00285     
00286     // Create the track extras and add the references to the rechits
00287     unsigned hits=0;
00288     unsigned nTracks = recoTracks->size();
00289     recoTrackExtras->reserve(nTracks); // To save some time at push_back
00290     for ( unsigned index = 0; index < nTracks; ++index ) { 
00291       //reco::TrackExtra aTrackExtra;
00292       reco::Track& aTrack = recoTracks->at(index);
00293       reco::TrackExtra aTrackExtra(aTrack.outerPosition(),
00294                                    aTrack.outerMomentum(),
00295                                    aTrack.outerOk(),
00296                                    aTrack.innerPosition(),
00297                                    aTrack.innerMomentum(),
00298                                    aTrack.innerOk(),
00299                                    aTrack.outerStateCovariance(),
00300                                    aTrack.outerDetId(),
00301                                    aTrack.innerStateCovariance(),
00302                                    aTrack.innerDetId(),
00303                                    aTrack.seedDirection(),
00304                                    aTrack.seedRef());
00305       
00306       unsigned nHits = aTrack.recHitsSize();
00307       for ( unsigned int ih=0; ih<nHits; ++ih) {
00308         aTrackExtra.add(TrackingRecHitRef(theRecoHits,hits++));
00309       }
00310       recoTrackExtras->push_back(aTrackExtra);
00311     }
00312     
00313     // Save the track extras
00314     edm::OrphanHandle<reco::TrackExtraCollection> theRecoTrackExtras = e.put(recoTrackExtras);
00315     
00316     // Add the reference to the track extra in the tracks
00317     for ( unsigned index = 0; index<nTracks; ++index ) { 
00318       const reco::TrackExtraRef theTrackExtraRef(theRecoTrackExtras,index);
00319       (recoTracks->at(index)).setExtra(theTrackExtraRef);
00320     }
00321     
00322     // Save the tracks
00323     edm::OrphanHandle<reco::TrackCollection> theRecoTracks = e.put(recoTracks);
00324     
00325     // Save the trajectories
00326     edm::OrphanHandle<std::vector<Trajectory> > theRecoTrajectories = e.put(recoTrajectories);
00327     
00328     // Create and set the trajectory/track association map 
00329     for ( unsigned index = 0; index<nTracks; ++index ) { 
00330       edm::Ref<std::vector<Trajectory> > trajRef( theRecoTrajectories, index );
00331       edm::Ref<reco::TrackCollection>    tkRef( theRecoTracks, index );
00332       recoTrajTrackMap->insert(trajRef,tkRef);
00333     }
00334     
00335     // Save the association map.
00336     e.put(recoTrajTrackMap);
00337     
00338   }
00339 
00340 }
00341 
00342 int 
00343 FastTrackMerger::findId(const reco::Track& aTrack) const {
00344   int trackId = -1;
00345   trackingRecHit_iterator aHit = aTrack.recHitsBegin();
00346   trackingRecHit_iterator lastHit = aTrack.recHitsEnd();
00347   for ( ; aHit!=lastHit; ++aHit ) {
00348     if ( !aHit->get()->isValid() ) continue;
00349     //    const SiTrackerGSRecHit2D * rechit = (const SiTrackerGSRecHit2D*) (aHit->get());
00350     const SiTrackerGSMatchedRecHit2D * rechit = (const SiTrackerGSMatchedRecHit2D*) (aHit->get());
00351     trackId = rechit->simtrackId();
00352     break;
00353   }
00354   return trackId;
00355 }
00356 
00357 

Generated on Tue Jun 9 17:35:14 2009 for CMSSW by  doxygen 1.5.4