CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FastSimulation/Tracking/plugins/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/TrackExtra.h"
00015 #include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
00016 
00017 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00018 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00019 
00020 #include "FastSimulation/Tracking/plugins/FastTrackMerger.h"
00021 
00022 #include <vector>
00023 #include <map>
00024 //
00025 
00026 //for debug only 
00027 //#define FAMOS_DEBUG
00028 
00029 FastTrackMerger::FastTrackMerger(const edm::ParameterSet& conf) 
00030 {  
00031 #ifdef FAMOS_DEBUG
00032   std::cout << "FastTrackMerger created" << std::endl;
00033 #endif
00034 
00035   // The main product is a track collection, and all extras
00036   produces<reco::TrackCollection>();
00037   
00038   // The name of the track producers to merge
00039   trackProducers = conf.getParameter<std::vector<edm::InputTag> >("TrackProducers");
00040 
00041   // The name of the track producers to remove
00042   std::vector<edm::InputTag> defaultRemove;
00043   removeTrackProducers = 
00044     conf.getUntrackedParameter<std::vector<edm::InputTag> >("RemoveTrackProducers",defaultRemove);
00045 
00046   // Only the tracks!
00047   tracksOnly = conf.getUntrackedParameter<bool>("SaveTracksOnly",false);
00048 
00049   // optional pT cut
00050   double pTMin = conf.getUntrackedParameter<bool>("pTMin",0.);
00051   pTMin2 = pTMin*pTMin;
00052 
00053   // optional nHit cut
00054   minHits = conf.getUntrackedParameter<unsigned>("minHits",0);
00055 
00056   // optional track quality saving
00057   promoteQuality = conf.getUntrackedParameter<bool>("promoteTrackQuality",false);
00058   qualityStr = conf.getUntrackedParameter<std::string>("newQuality","");
00059 
00060   // optional trackAlgo (iter0/1/2/3/4)
00061   trackAlgo = conf.getUntrackedParameter<unsigned>("trackAlgo",0);
00062 
00063   //new parameters for Trajectory filtering
00064 
00065   // The minimum number of hits
00066   theMinimumNumberOfHits = conf.getUntrackedParameter<unsigned>("MinNumberOfTrajHits",0);
00067 
00068   // The maximum number of Lost Hits
00069   theMaxLostHits = conf.getUntrackedParameter<unsigned>("MaxLostTrajHits",99);
00070 
00071   // the max number of consecutive Lost Hits 
00072   theMaxConsecutiveLostHits = conf.getUntrackedParameter<unsigned>("MaxConsecutiveLostTrajHits",3);
00073 
00074   //======================
00075 
00076   if ( !tracksOnly ) { 
00077     produces<reco::TrackExtraCollection>();
00078     produces<TrackingRecHitCollection>();
00079     produces<std::vector<Trajectory> >();
00080     produces<TrajTrackAssociationCollection>();
00081   } else {
00082     produces<reco::TrackExtraCollection>();
00083     produces<TrackingRecHitCollection>();
00084   }
00085 }
00086 
00087   
00088 // Functions that gets called by framework every event
00089 void 
00090 FastTrackMerger::produce(edm::Event& e, const edm::EventSetup& es) {        
00091 
00092 #ifdef FAMOS_DEBUG
00093   std::cout << "################################################################" << std::endl;
00094   std::cout << " FastTrackMerger produce init " << std::endl;
00095 #endif
00096 
00097   // The track algorithm (only of merging after iterative tracking)
00098   reco::TrackBase::TrackAlgorithm algo;
00099   switch(trackAlgo)  {
00100   case 4:  algo = reco::TrackBase::iter0; break;
00101   case 5:  algo = reco::TrackBase::iter1; break;
00102   case 6:  algo = reco::TrackBase::iter2; break;
00103   case 7:  algo = reco::TrackBase::iter3; break;
00104   case 8:  algo = reco::TrackBase::iter4; break;
00105   case 9:  algo = reco::TrackBase::iter5; break;
00106   case 10: algo = reco::TrackBase::iter6; break;
00107   default: algo = reco::TrackBase::undefAlgorithm;
00108   }
00109 
00110   // The produced objects
00111   std::auto_ptr<reco::TrackCollection> recoTracks(new reco::TrackCollection);
00112   std::auto_ptr<reco::TrackExtraCollection> recoTrackExtras(new reco::TrackExtraCollection);
00113   std::auto_ptr<TrackingRecHitCollection> recoHits(new TrackingRecHitCollection);
00114   std::auto_ptr<std::vector<Trajectory> > recoTrajectories(new std::vector<Trajectory>);
00115   std::auto_ptr<TrajTrackAssociationCollection> recoTrajTrackMap(new TrajTrackAssociationCollection());
00116 
00117   //prepare the ref to copy the extras
00118   reco::TrackExtraRefProd rTrackExtras = e.getRefBeforePut<reco::TrackExtraCollection>();
00119   TrackingRecHitRefProd rHits = e.getRefBeforePut<TrackingRecHitCollection>();
00120   std::vector<reco::TrackRef> trackRefs;
00121 
00122   // No seed -> output an empty track collection
00123   if(trackProducers.size() == 0) {
00124     e.put(recoTracks);
00125     if ( !tracksOnly ) { 
00126       e.put(recoTrackExtras);
00127       e.put(recoHits);
00128       e.put(recoTrajectories);
00129       e.put(recoTrajTrackMap);
00130     } else {
00131       e.put(recoTrackExtras);
00132       e.put(recoHits);
00133     }
00134     return;
00135   }
00136 
00137   // The quality to be set
00138   reco::TrackBase::TrackQuality qualityToSet;
00139   if (qualityStr != "")
00140     qualityToSet = reco::TrackBase::qualityByName(qualityStr);
00141   else 
00142     qualityToSet = reco::TrackBase::undefQuality;
00143 
00144   // The input track collection handle
00145   edm::Handle<reco::TrackCollection> theTrackCollection;
00146 
00147   // First, the tracks to be removed
00148   std::set<unsigned> removeTracks;
00149   for ( unsigned aProducer=0; aProducer<removeTrackProducers.size(); ++aProducer ) { 
00150     bool isTrackCollection = e.getByLabel(removeTrackProducers[aProducer],theTrackCollection); 
00151     if (!isTrackCollection) continue;
00152     reco::TrackCollection::const_iterator aTrack = theTrackCollection->begin();
00153     reco::TrackCollection::const_iterator lastTrack = theTrackCollection->end();
00154     for ( ; aTrack!=lastTrack; ++aTrack ) {
00155       // Get the simtrack Id
00156       int recoTrackId = findId(*aTrack);
00157       if ( recoTrackId < 0 ) continue;
00158       // Remove the track if requested
00159       if ( removeTracks.find((unsigned)recoTrackId) != removeTracks.end() ) continue;
00160       removeTracks.insert((unsigned)recoTrackId);
00161     }      
00162   }
00163   
00164   // Then the tracks to be added
00165   std::set<unsigned> alreadyAddedTracks;
00166   
00167   // Loop on the track producers to be merged
00168   for ( unsigned aProducer=0; aProducer<trackProducers.size(); ++aProducer ) { 
00169     
00170     bool isTrackCollection = e.getByLabel(trackProducers[aProducer],theTrackCollection); 
00171     if ( ! isTrackCollection ) { 
00172 #ifdef FAMOS_DEBUG
00173       std::cout << "***FastTrackMerger*** Warning! The track collection " 
00174                 << trackProducers[aProducer].encode() 
00175                 << " does not exist." << std::endl;
00176 #endif
00177       continue;
00178     }
00179 
00180 #ifdef FAMOS_DEBUG
00181     std::cout << "***FastTrackMerger*** of track collection " 
00182               << trackProducers[aProducer].encode() 
00183               << " with " << theTrackCollection->size() 
00184               << " tracks to be copied"
00185               << std::endl;
00186 #endif
00187     reco::TrackCollection::const_iterator aTrack = theTrackCollection->begin();
00188     reco::TrackCollection::const_iterator lastTrack = theTrackCollection->end();
00189 
00190     //Copy Tracks and TracksExtra 
00191     if ( tracksOnly ) { 
00192 
00193       edm:: Handle<reco::TrackExtraCollection > theTrackExtraCollection;
00194       //      bool isTrackExtraCollection = e.getByLabel(trackProducers[aProducer],theTrackExtraCollection); 
00195 
00196       bool index = 0;
00197       for ( ; aTrack!=lastTrack; ++aTrack,++index ) {
00198 
00199         // Find the track id
00200         int recoTrackId = findId(*aTrack);
00201         if ( recoTrackId < 0 ) continue;
00202         
00203         // Ignore tracks to be removed or tracks already copied
00204         std::set<unsigned>::iterator iR = removeTracks.find((unsigned)recoTrackId);
00205 #ifdef FAMOS_DEBUG
00206         if( iR != removeTracks.end() ) std::cout << recoTrackId << "(REMOVED) ";
00207 #endif
00208         if( iR != removeTracks.end() ) continue;
00209         
00210         // Ignore tracks already copied
00211         std::set<unsigned>::iterator iA = alreadyAddedTracks.find((unsigned)recoTrackId);
00212 #ifdef FAMOS_DEBUG
00213         if( iA != alreadyAddedTracks.end() ) std::cout << recoTrackId << "(ALREADY ADDED) ";
00214 #endif
00215         if( iA != alreadyAddedTracks.end() ) continue;
00216         //if it is not there then add it! 
00217         alreadyAddedTracks.insert(recoTrackId);
00218 
00219         
00220 #ifdef FAMOS_DEBUG
00221         std::cout << recoTrackId << " ADDED ";
00222 #endif
00223 
00224         // Ignore tracks with too small a pT
00225 #ifdef FAMOS_DEBUG
00226         if ( aTrack->innerMomentum().Perp2() < pTMin2 ) 
00227           std::cout << "PTMIN CUT APPLIED = " <<  aTrack->innerMomentum().Perp2() << std::endl;
00228 #endif
00229 
00230         if ( aTrack->innerMomentum().Perp2() < pTMin2 ) continue;
00231         
00232         // Ignore tracks with too small a pT
00233         if ( aTrack->recHitsSize() < minHits ) continue;
00234         
00235         // A copy of the track + save the transient reference to the track extra reference
00236         reco::Track aRecoTrack(*aTrack);
00237         recoTracks->push_back(aRecoTrack);
00238         
00239 
00240         recoTrackExtras->push_back(reco::TrackExtra(aRecoTrack.outerPosition(), aRecoTrack.outerMomentum(), aRecoTrack.outerOk(),
00241                                                aRecoTrack.innerPosition(), aRecoTrack.innerMomentum(), aRecoTrack.innerOk(),
00242                                                aRecoTrack.outerStateCovariance(), aRecoTrack.outerDetId(),
00243                                                aRecoTrack.innerStateCovariance(), aRecoTrack.innerDetId(),
00244                                                aRecoTrack.seedDirection(), aRecoTrack.seedRef() ) ); 
00245 
00246 
00247         recoTracks->back().setExtra(reco::TrackExtraRef(rTrackExtras,recoTrackExtras->size()-1)); 
00248 
00249         reco::TrackExtra & tx = recoTrackExtras->back();
00250         tx.setResiduals(aRecoTrack.residuals());
00251         //TrackingRecHits
00252         for( trackingRecHit_iterator hit = aRecoTrack.recHitsBegin(); hit != aRecoTrack.recHitsEnd(); ++ hit ) {
00253           recoHits->push_back( (*hit)->clone() );
00254           tx.add( TrackingRecHitRef( rHits , recoHits->size() - 1) );
00255         }
00256         
00257         // Save the quality if requested
00258         if (promoteQuality) recoTracks->back().setQuality(qualityToSet);
00259         if ( trackAlgo ) recoTracks->back().setAlgorithm(algo);
00260         
00261       }
00262       
00263       
00264       // All extras are to be copied too -> loop on the Trajectory/Track map association 
00265     } else { 
00266       
00267       edm:: Handle<std::vector<Trajectory> > theTrajectoryCollection;
00268       edm::Handle<TrajTrackAssociationCollection> theAssoMap;  
00269 
00270       // Count the number of hits and reserve appropriate memory
00271       unsigned nRecoHits = 0;
00272       for ( ; aTrack!=lastTrack; ++aTrack ) nRecoHits+= aTrack->recHitsSize();
00273       recoHits->reserve(nRecoHits); // This is to save some time at push_back.
00274       
00275       e.getByLabel(trackProducers[aProducer],theTrajectoryCollection);
00276       e.getByLabel(trackProducers[aProducer],theAssoMap);
00277       
00278       // The track collection iterators.
00279       TrajTrackAssociationCollection::const_iterator anAssociation;  
00280       TrajTrackAssociationCollection::const_iterator lastAssociation;
00281       anAssociation = theAssoMap->begin();
00282       lastAssociation = theAssoMap->end();
00283 #ifdef FAMOS_DEBUG
00284       std::cout << "List of tracks to be copied " << std::endl;
00285 #endif
00286       // Build the map of correspondance between reco tracks and sim tracks
00287       for ( ; anAssociation != lastAssociation; ++anAssociation ) { 
00288         edm::Ref<std::vector<Trajectory> > aTrajectoryRef = anAssociation->key;
00289         reco::TrackRef aTrackRef = anAssociation->val;
00290         // Find the track id
00291         int recoTrackId = findId(*aTrackRef);
00292         if ( recoTrackId < 0 ) continue;
00293         
00294         // Ignore tracks to be removed or tracks already copied
00295         std::set<unsigned>::iterator iR = removeTracks.find((unsigned)recoTrackId);
00296 #ifdef FAMOS_DEBUG
00297         if( iR != removeTracks.end() ) std::cout << recoTrackId << "(REMOVED) ";
00298 #endif
00299         if( iR != removeTracks.end() ) continue;
00300         
00301         // Ignore tracks already copied
00302         std::set<unsigned>::iterator iA = alreadyAddedTracks.find((unsigned)recoTrackId);
00303 #ifdef FAMOS_DEBUG
00304         if( iA != alreadyAddedTracks.end() ) std::cout << recoTrackId << "(ALREADY ADDED) ";
00305 #endif
00306         if( iA != alreadyAddedTracks.end() ) continue;
00307         
00308 #ifdef FAMOS_DEBUG
00309         std::cout << recoTrackId << " Newly Added " << std::endl;
00310 #endif
00311         //if it is not there then add it! 
00312         alreadyAddedTracks.insert(recoTrackId);
00313         
00314         // Ignore tracks with too small a pT
00315         if ( aTrackRef->innerMomentum().Perp2() < pTMin2 ) continue;
00316         
00317         // Ignore tracks with too few hits
00318         if ( aTrackRef->recHitsSize() < minHits ) continue;
00319         
00320         //==== add more cuts on the trajectory (emulate the Trajectory Filter) 
00321 
00322 #ifdef FAMOS_DEBUG
00323         if(aTrajectoryRef->lostHits() > theMaxLostHits )
00324           std::cout << "\tmaxLostHits= " << aTrajectoryRef->lostHits() << "\tCUT =" << theMaxLostHits << std::endl;
00325 #endif
00326 
00327         if((unsigned)aTrajectoryRef->lostHits() > theMaxLostHits ) continue;
00328 
00329 #ifdef FAMOS_DEBUG
00330         if(aTrajectoryRef->foundHits() < theMinimumNumberOfHits )
00331           std::cout << "\tMinimumNumberOfHits = " <<  aTrajectoryRef->foundHits() << "\tCUT = " <<theMinimumNumberOfHits <<  std::endl;
00332 #endif
00333         
00334         if((unsigned)aTrajectoryRef->foundHits() < theMinimumNumberOfHits ) continue;
00335         //calculate the consecutive Lost Hits
00336         unsigned consecLostHits = 0;
00337         const std::vector<TrajectoryMeasurement> tms = aTrajectoryRef->measurements();
00338         for(int itm= tms.size();itm!=0; --itm){
00339           if(tms[itm-1].recHit()->isValid())break;
00340           else if (Trajectory::lost(*tms[itm-1].recHit())) consecLostHits++;
00341         }
00342 
00343 #ifdef FAMOS_DEBUG
00344         if( consecLostHits > theMaxConsecutiveLostHits ) 
00345           std::cout << "\tconsecLostHits = " << consecLostHits << std::endl;
00346 #endif
00347 
00348         if( consecLostHits > theMaxConsecutiveLostHits ) continue;
00349 
00350 
00351         //=============end new filters
00352 
00353 
00354         // A copy of the track
00355         reco::Track aRecoTrack(*aTrackRef);
00356         recoTracks->push_back(aRecoTrack);      
00357         // Save the quality if requested
00358         if (promoteQuality) recoTracks->back().setQuality(qualityToSet);        
00359         if ( trackAlgo ) recoTracks->back().setAlgorithm(algo);
00360         
00361      
00362         // A copy of the hits
00363         unsigned nh = aRecoTrack.recHitsSize();
00364         for ( unsigned ih=0; ih<nh; ++ih ) {
00365           TrackingRecHit *hit = aRecoTrack.recHit(ih)->clone();
00366           recoHits->push_back(hit);
00367         }
00368         
00369         // A copy of the trajectories
00370         recoTrajectories->push_back(*aTrajectoryRef);
00371         
00372       }
00373 #ifdef FAMOS_DEBUG
00374       std::cout << std::endl;
00375 #endif
00376     }
00377 }
00378     
00379     // Save the track candidates in the event
00380 #ifdef FAMOS_DEBUG
00381   std::cout << "Saving " 
00382             << recoTracks->size() << " reco::Tracks " << std::endl;
00383 
00384 #endif
00385   
00386   if ( tracksOnly ) { 
00387     // Save only the tracks (with transient reference to track extras)
00388     e.put(recoTracks);
00389     e.put(recoTrackExtras);
00390     e.put(recoHits);
00391 
00392 
00393   } else { 
00394     // Save the tracking recHits
00395     edm::OrphanHandle <TrackingRecHitCollection> theRecoHits = e.put(recoHits );
00396     
00397     // Create the track extras and add the references to the rechits
00398     unsigned hits=0;
00399     unsigned nTracks = recoTracks->size();
00400     recoTrackExtras->reserve(nTracks); // To save some time at push_back
00401     for ( unsigned index = 0; index < nTracks; ++index ) { 
00402 
00403       //reco::TrackExtra aTrackExtra;
00404       reco::Track& aTrack = recoTracks->at(index);
00405 
00406       // std::cout << "initial TrackAlgo = " << trackAlgo << "\tNAME " << aTrack.algoName() << "\tnumber = " << aTrack.algo() << std::endl;
00407 
00408       reco::TrackExtra aTrackExtra(aTrack.outerPosition(),
00409                                    aTrack.outerMomentum(),
00410                                    aTrack.outerOk(),
00411                                    aTrack.innerPosition(),
00412                                    aTrack.innerMomentum(),
00413                                    aTrack.innerOk(),
00414                                    aTrack.outerStateCovariance(),
00415                                    aTrack.outerDetId(),
00416                                    aTrack.innerStateCovariance(),
00417                                    aTrack.innerDetId(),
00418                                    aTrack.seedDirection(),
00419                                    aTrack.seedRef());
00420       
00421       unsigned nHits = aTrack.recHitsSize();
00422       for ( unsigned int ih=0; ih<nHits; ++ih) {
00423         aTrackExtra.add(TrackingRecHitRef(theRecoHits,hits++));
00424       }
00425       recoTrackExtras->push_back(aTrackExtra);
00426     }
00427     
00428     // Save the track extras
00429     edm::OrphanHandle<reco::TrackExtraCollection> theRecoTrackExtras = e.put(recoTrackExtras);
00430     
00431     // Add the reference to the track extra in the tracks
00432     for ( unsigned index = 0; index<nTracks; ++index ) { 
00433       const reco::TrackExtraRef theTrackExtraRef(theRecoTrackExtras,index);
00434       (recoTracks->at(index)).setExtra(theTrackExtraRef);
00435     }
00436     
00437     // Save the tracks
00438     edm::OrphanHandle<reco::TrackCollection> theRecoTracks = e.put(recoTracks);
00439     
00440     // Save the trajectories
00441     edm::OrphanHandle<std::vector<Trajectory> > theRecoTrajectories = e.put(recoTrajectories);
00442     
00443     // Create and set the trajectory/track association map 
00444     for ( unsigned index = 0; index<nTracks; ++index ) { 
00445       edm::Ref<std::vector<Trajectory> > trajRef( theRecoTrajectories, index );
00446       edm::Ref<reco::TrackCollection>    tkRef( theRecoTracks, index );
00447       recoTrajTrackMap->insert(trajRef,tkRef);
00448     }
00449     
00450     // Save the association map.
00451     e.put(recoTrajTrackMap);
00452     
00453   }
00454 
00455 }
00456 
00457 int 
00458 FastTrackMerger::findId(const reco::Track& aTrack) const {
00459   int trackId = -1;
00460   trackingRecHit_iterator aHit = aTrack.recHitsBegin();
00461   trackingRecHit_iterator lastHit = aTrack.recHitsEnd();
00462   for ( ; aHit!=lastHit; ++aHit ) {
00463     if ( !aHit->get()->isValid() ) continue;
00464     //    const SiTrackerGSRecHit2D * rechit = (const SiTrackerGSRecHit2D*) (aHit->get());
00465     const SiTrackerGSMatchedRecHit2D * rechit = (const SiTrackerGSMatchedRecHit2D*) (aHit->get());
00466     trackId = rechit->simtrackId();
00467     break;
00468   }
00469   return trackId;
00470 }
00471 
00472