CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoTracker/CkfPattern/src/CkfTrackCandidateMakerBase.cc

Go to the documentation of this file.
00001 #include <memory>
00002 #include <string>
00003 
00004 #include "DataFormats/Common/interface/Handle.h"
00005 #include "FWCore/Framework/interface/ESHandle.h"
00006 #include "FWCore/Framework/interface/EventSetup.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 #include "DataFormats/Common/interface/OwnVector.h"
00010 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00011 #include "DataFormats/Common/interface/View.h"
00012 
00013 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00014 
00015 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00016 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
00017 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00018 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00019 
00020 #include "RecoTracker/CkfPattern/interface/CkfTrackCandidateMakerBase.h"
00021 #include "RecoTracker/CkfPattern/interface/TransientInitialStateEstimator.h"
00022 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00023 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00024 
00025 
00026 #include "RecoTracker/CkfPattern/interface/SeedCleanerByHitPosition.h"
00027 #include "RecoTracker/CkfPattern/interface/CachingSeedCleanerByHitPosition.h"
00028 #include "RecoTracker/CkfPattern/interface/SeedCleanerBySharedInput.h"
00029 #include "RecoTracker/CkfPattern/interface/CachingSeedCleanerBySharedInput.h"
00030 
00031 #include "RecoTracker/Record/interface/NavigationSchoolRecord.h"
00032 #include "TrackingTools/DetLayers/interface/NavigationSchool.h"
00033 
00034 #include<algorithm>
00035 #include<functional>
00036 
00037 #include "RecoTracker/CkfPattern/interface/PrintoutHelper.h"
00038 
00039 using namespace edm;
00040 using namespace std;
00041 
00042 namespace cms{
00043   CkfTrackCandidateMakerBase::CkfTrackCandidateMakerBase(edm::ParameterSet const& conf) : 
00044 
00045     conf_(conf),
00046     theTrackCandidateOutput(true),
00047     theTrajectoryOutput(false),
00048     useSplitting(conf.getParameter<bool>("useHitsSplitting")),
00049     doSeedingRegionRebuilding(conf.getParameter<bool>("doSeedingRegionRebuilding")),
00050     cleanTrajectoryAfterInOut(conf.getParameter<bool>("cleanTrajectoryAfterInOut")),
00051     reverseTrajectories(conf.existsAs<bool>("reverseTrajectories") && conf.getParameter<bool>("reverseTrajectories")),
00052     theMaxNSeeds(conf.getParameter<unsigned int>("maxNSeeds")),
00053     theTrajectoryBuilderName(conf.getParameter<std::string>("TrajectoryBuilder")), 
00054     theTrajectoryBuilder(0),
00055     theTrajectoryCleanerName(conf.getParameter<std::string>("TrajectoryCleaner")), 
00056     theTrajectoryCleaner(0),
00057     theInitialState(0),
00058     theNavigationSchoolName(conf.getParameter<std::string>("NavigationSchool")),
00059     theNavigationSchool(0),
00060     theSeedCleaner(0),
00061     maxSeedsBeforeCleaning_(0)
00062   {  
00063     //produces<TrackCandidateCollection>();  
00064     // old configuration totally descoped.
00065     //    if (!conf.exists("src"))
00066     //      theSeedLabel = InputTag(conf_.getParameter<std::string>("SeedProducer"),conf_.getParameter<std::string>("SeedLabel"));
00067     //    else
00068       theSeedLabel= conf.getParameter<edm::InputTag>("src");
00069       if ( conf.exists("maxSeedsBeforeCleaning") ) 
00070            maxSeedsBeforeCleaning_=conf.getParameter<unsigned int>("maxSeedsBeforeCleaning");
00071 
00072   }
00073 
00074   
00075   // Virtual destructor needed.
00076   CkfTrackCandidateMakerBase::~CkfTrackCandidateMakerBase() {
00077     delete theInitialState;  
00078     if (theSeedCleaner) delete theSeedCleaner;
00079   }  
00080 
00081   void CkfTrackCandidateMakerBase::beginRunBase (edm::Run & r, EventSetup const & es)
00082   {
00083     std::string cleaner = conf_.getParameter<std::string>("RedundantSeedCleaner");
00084     if (cleaner == "SeedCleanerByHitPosition") {
00085         theSeedCleaner = new SeedCleanerByHitPosition();
00086     } else if (cleaner == "SeedCleanerBySharedInput") {
00087         theSeedCleaner = new SeedCleanerBySharedInput();
00088     } else if (cleaner == "CachingSeedCleanerByHitPosition") {
00089         theSeedCleaner = new CachingSeedCleanerByHitPosition();
00090     } else if (cleaner == "CachingSeedCleanerBySharedInput") {
00091       int numHitsForSeedCleaner = conf_.existsAs<int>("numHitsForSeedCleaner") ? 
00092         conf_.getParameter<int>("numHitsForSeedCleaner") : 4;
00093       int onlyPixelHits = conf_.existsAs<bool>("onlyPixelHitsForSeedCleaner") ? 
00094         conf_.getParameter<bool>("onlyPixelHitsForSeedCleaner") : false;
00095       theSeedCleaner = new CachingSeedCleanerBySharedInput(numHitsForSeedCleaner,onlyPixelHits);
00096     } else if (cleaner == "none") {
00097         theSeedCleaner = 0;
00098     } else {
00099         throw cms::Exception("RedundantSeedCleaner not found", cleaner);
00100     }
00101   }
00102 
00103   void CkfTrackCandidateMakerBase::setEventSetup( const edm::EventSetup& es ) {
00104 
00105     //services
00106     es.get<TrackerRecoGeometryRecord>().get( theGeomSearchTracker );
00107     es.get<IdealMagneticFieldRecord>().get( theMagField );
00108 
00109     if (!theInitialState){
00110       // constructor uses the EventSetup, it must be in the setEventSetup were it has a proper value.
00111       // get nested parameter set for the TransientInitialStateEstimator
00112       ParameterSet tise_params = conf_.getParameter<ParameterSet>("TransientInitialStateEstimatorParameters") ;
00113       theInitialState          = new TransientInitialStateEstimator( es,tise_params);
00114     }
00115 
00116     theInitialState->setEventSetup( es );
00117 
00118     edm::ESHandle<TrajectoryCleaner> trajectoryCleanerH;
00119     es.get<TrajectoryCleaner::Record>().get(theTrajectoryCleanerName, trajectoryCleanerH);
00120     theTrajectoryCleaner= trajectoryCleanerH.product();
00121 
00122     edm::ESHandle<NavigationSchool> navigationSchoolH;
00123     es.get<NavigationSchoolRecord>().get(theNavigationSchoolName, navigationSchoolH);
00124     theNavigationSchool = navigationSchoolH.product();
00125 
00126     // set the TrajectoryBuilder
00127     edm::ESHandle<TrajectoryBuilder> theTrajectoryBuilderHandle;
00128     es.get<CkfComponentsRecord>().get(theTrajectoryBuilderName,theTrajectoryBuilderHandle);
00129     theTrajectoryBuilder = theTrajectoryBuilderHandle.product();    
00130        
00131   }
00132 
00133   // Functions that gets called by framework every event
00134   void CkfTrackCandidateMakerBase::produceBase(edm::Event& e, const edm::EventSetup& es)
00135   { 
00136     // getting objects from the EventSetup
00137     setEventSetup( es ); 
00138 
00139     // set the correct navigation
00140     NavigationSetter setter( *theNavigationSchool);
00141     
00142     // propagator
00143     edm::ESHandle<Propagator> thePropagator;
00144     es.get<TrackingComponentsRecord>().get("AnyDirectionAnalyticalPropagator",
00145                                            thePropagator);
00146 
00147     // method for Debugging
00148     printHitsDebugger(e);
00149 
00150     // Step A: set Event for the TrajectoryBuilder
00151     theTrajectoryBuilder->setEvent(e);        
00152     
00153     // Step B: Retrieve seeds
00154     
00155     edm::Handle<View<TrajectorySeed> > collseed;
00156     e.getByLabel(theSeedLabel, collseed);
00157     
00158     // Step C: Create empty output collection
00159     std::auto_ptr<TrackCandidateCollection> output(new TrackCandidateCollection);    
00160     std::auto_ptr<std::vector<Trajectory> > outputT (new std::vector<Trajectory>());
00161 
00162     if ( (*collseed).size()>theMaxNSeeds ) {
00163       LogError("TooManySeeds")<<"Exceeded maximum numeber of seeds! theMaxNSeeds="<<theMaxNSeeds<<" nSeed="<<(*collseed).size();
00164       if (theTrackCandidateOutput){ e.put(output);}
00165       if (theTrajectoryOutput){e.put(outputT);}
00166       theTrajectoryBuilder->unset();
00167       return;
00168     }
00169     
00170     // Step D: Invoke the building algorithm
00171     if ((*collseed).size()>0){
00172 
00173       unsigned int lastCleanResult=0;
00174        vector<Trajectory> rawResult;
00175        rawResult.reserve(collseed->size() * 4);
00176 
00177       if (theSeedCleaner) theSeedCleaner->init( &rawResult );
00178       
00179       // method for debugging
00180       countSeedsDebugger();
00181 
00182       vector<Trajectory> theTmpTrajectories;
00183 
00184       // Loop over seeds
00185       size_t collseed_size = collseed->size(); 
00186       for (size_t j = 0; j < collseed_size; j++){
00187        
00188         // Check if seed hits already used by another track
00189         if (theSeedCleaner && !theSeedCleaner->good( &((*collseed)[j])) ) {
00190           LogDebug("CkfTrackCandidateMakerBase")<<" Seed cleaning kills seed "<<j;
00191           continue; 
00192         }
00193 
00194         // Build trajectory from seed outwards
00195         theTmpTrajectories.clear();
00196         theTrajectoryBuilder->trajectories( (*collseed)[j], theTmpTrajectories );
00197         
00198        
00199         LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
00200                                     << " trajectories from seed " << j << " ========"<<endl
00201                                <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
00202         
00203         if (cleanTrajectoryAfterInOut) {
00204 
00205           // Select the best trajectory from this seed (declare others invalid)
00206           theTrajectoryCleaner->clean(theTmpTrajectories);
00207 
00208           LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following valid trajectories from seed " 
00209                                  << j << " ========"<<endl
00210                                  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
00211         }
00212 
00213         // Optionally continue building trajectory back through 
00214         // seed and if possible further inwards.
00215         
00216         if (doSeedingRegionRebuilding) {
00217           theTrajectoryBuilder->rebuildSeedingRegion((*collseed)[j],theTmpTrajectories);      
00218 
00219           LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
00220                                       << " valid/invalid trajectories from seed " << j << " ========"<<endl
00221                                  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
00222         }
00223         
00224 
00225         // Select the best trajectory from this seed (after seed region rebuilding, can be more than one)
00226         theTrajectoryCleaner->clean(theTmpTrajectories);
00227 
00228         LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following valid trajectories from seed " 
00229                                << j << " ========"<<endl
00230                                <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
00231 
00232         for(vector<Trajectory>::iterator it=theTmpTrajectories.begin();
00233             it!=theTmpTrajectories.end(); it++){
00234           if( it->isValid() ) {
00235             it->setSeedRef(collseed->refAt(j));
00236             // Store trajectory
00237             rawResult.push_back(*it);
00238             // Tell seed cleaner which hits this trajectory used.
00239             //TO BE FIXED: this cut should be configurable via cfi file
00240             if (theSeedCleaner && it->foundHits()>3) theSeedCleaner->add( & (*it) );
00241             //if (theSeedCleaner ) theSeedCleaner->add( & (*it) );
00242           }
00243         }
00244 
00245         theTmpTrajectories.clear();
00246         
00247         LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
00248 
00249         if ( maxSeedsBeforeCleaning_ >0 && rawResult.size() > maxSeedsBeforeCleaning_+lastCleanResult) {
00250           theTrajectoryCleaner->clean(rawResult);
00251           rawResult.erase(std::remove_if(rawResult.begin(),rawResult.end(),
00252                                          std::not1(std::mem_fun_ref(&Trajectory::isValid))),
00253                           rawResult.end());
00254           lastCleanResult=rawResult.size();
00255         }
00256 
00257       }
00258       // end of loop over seeds
00259       
00260       if (theSeedCleaner) theSeedCleaner->done();
00261       
00262       // Step E: Clean the results to avoid duplicate tracks
00263       // Rejected ones just flagged as invalid.
00264       theTrajectoryCleaner->clean(rawResult);
00265 
00266       LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size() 
00267                              << " valid/invalid trajectories ======="<<endl
00268                              <<PrintoutHelper::dumpCandidates(rawResult);
00269 
00270       LogDebug("CkfPattern") << "removing invalid trajectories.";
00271 
00272       vector<Trajectory> & unsmoothedResult(rawResult);
00273       unsmoothedResult.erase(std::remove_if(unsmoothedResult.begin(),unsmoothedResult.end(),
00274                                             std::not1(std::mem_fun_ref(&Trajectory::isValid))),
00275                              unsmoothedResult.end());
00276       
00277       // If requested, reverse the trajectories creating a new 1-hit seed on the last measurement of the track
00278       if (reverseTrajectories) {
00279         vector<Trajectory> reversed; 
00280         reversed.reserve(unsmoothedResult.size());
00281         for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
00282           // reverse the trajectory only if it has valid hit on the last measurement (should happen)
00283           if (it->lastMeasurement().updatedState().isValid() && 
00284               it->lastMeasurement().recHit().get() != 0     &&
00285               it->lastMeasurement().recHit()->isValid()) {
00286             // I can't use reverse in place, because I want to change the seed
00287             // 1) reverse propagation direction
00288             PropagationDirection direction = it->direction();
00289             if (direction == alongMomentum)           direction = oppositeToMomentum;
00290             else if (direction == oppositeToMomentum) direction = alongMomentum;
00291             // 2) make a seed
00292             TrajectoryStateOnSurface initState = it->lastMeasurement().updatedState();
00293             DetId                    initDetId = it->lastMeasurement().recHit()->geographicalId();
00294             PTrajectoryStateOnDet state = trajectoryStateTransform::persistentState( initState, initDetId.rawId());
00295             TrajectorySeed::recHitContainer hits; 
00296             hits.push_back(*it->lastMeasurement().recHit()->hit());
00297             boost::shared_ptr<const TrajectorySeed> seed(new TrajectorySeed(state, hits, direction));
00298             // 3) make a trajectory
00299             Trajectory trajectory(seed, direction);
00300             trajectory.setNLoops(it->nLoops());
00301             trajectory.setSeedRef(it->seedRef());
00302             // 4) push states in reversed order
00303             const Trajectory::DataContainer &meas = it->measurements();
00304             for (Trajectory::DataContainer::const_reverse_iterator itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
00305               trajectory.push(*itmeas);
00306             } 
00307             reversed.push_back(trajectory);
00308           } else {
00309             edm::LogWarning("CkfPattern_InvalidLastMeasurement") << "Last measurement of the trajectory is invalid, cannot reverse it";
00310             reversed.push_back(*it);
00311           }     
00312         }
00313         unsmoothedResult.swap(reversed);
00314       }
00315 
00316       //      for (vector<Trajectory>::const_iterator itraw = rawResult.begin();
00317       //           itraw != rawResult.end(); itraw++) {
00318       //if((*itraw).isValid()) unsmoothedResult.push_back( *itraw);
00319       //}
00320 
00321       //analyseCleanedTrajectories(unsmoothedResult);
00322       
00323       if (theTrackCandidateOutput){
00324         // Step F: Convert to TrackCandidates
00325        output->reserve(unsmoothedResult.size());
00326        for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin();
00327             it != unsmoothedResult.end(); ++it) {
00328         
00329          Trajectory::RecHitContainer thits;
00330          //it->recHitsV(thits);
00331          LogDebug("CkfPattern") << "retrieving "<<(useSplitting?"splitted":"un-splitted")<<" hits from trajectory";
00332          it->recHitsV(thits,useSplitting);
00333          OwnVector<TrackingRecHit> recHits;
00334          recHits.reserve(thits.size());
00335          LogDebug("CkfPattern") << "cloning hits into new collection.";
00336          for (Trajectory::RecHitContainer::const_iterator hitIt = thits.begin();
00337               hitIt != thits.end(); ++hitIt) {
00338            recHits.push_back( (**hitIt).hit()->clone());
00339          }
00340 
00341          LogDebug("CkfPattern") << "getting initial state.";
00342          const bool doBackFit = !doSeedingRegionRebuilding && !reverseTrajectories;
00343          std::pair<TrajectoryStateOnSurface, const GeomDet*> initState = 
00344            theInitialState->innerState( *it , doBackFit);
00345 
00346          // temporary protection againt invalid initial states
00347          if (! initState.first.isValid() || initState.second == 0 || std::isnan(initState.first.globalPosition().x())) {
00348            //cout << "invalid innerState, will not make TrackCandidate" << endl;
00349            continue;
00350          }
00351          
00352          PTrajectoryStateOnDet state;
00353          if(useSplitting && (initState.second != thits.front()->det()) && thits.front()->det() ){        
00354            LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
00355            TrajectoryStateOnSurface propagated = thePropagator->propagate(initState.first,thits.front()->det()->surface());
00356            if (!propagated.isValid()) continue;
00357            state = trajectoryStateTransform::persistentState(propagated,
00358                                                                       thits.front()->det()->geographicalId().rawId());
00359          }
00360          else state = trajectoryStateTransform::persistentState( initState.first,
00361                                                                         initState.second->geographicalId().rawId());
00362          LogDebug("CkfPattern") << "pushing a TrackCandidate.";
00363          output->push_back(TrackCandidate(recHits,it->seed(),state,it->seedRef(),it->nLoops() ) );
00364        }
00365       }//output trackcandidates
00366 
00367       edm::ESHandle<TrackerGeometry> tracker;
00368       es.get<TrackerDigiGeometryRecord>().get(tracker);            
00369       LogTrace("CkfPattern|TrackingRegressionTest") << "========== CkfTrackCandidateMaker Info =========="
00370                                                     << "number of Seed: " << collseed->size()<<endl
00371                                                     <<PrintoutHelper::regressionTest(*tracker,unsmoothedResult);
00372 
00373       
00374      
00375       if (theTrajectoryOutput){ outputT->swap(unsmoothedResult);}
00376 
00377     }// end of ((*collseed).size()>0)
00378     
00379     // method for debugging
00380     deleteAssocDebugger();
00381 
00382     // Step G: write output to file
00383     if (theTrackCandidateOutput){ e.put(output);}
00384     if (theTrajectoryOutput){e.put(outputT);}
00385     
00386     //reset the MT.
00387     theTrajectoryBuilder->unset();
00388   }
00389   
00390 }
00391