CMS 3D CMS Logo

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