CMS 3D CMS Logo

GroupedCkfTrajectoryBuilder.cc

Go to the documentation of this file.
00001 #include "RecoTracker/CkfPattern/interface/GroupedCkfTrajectoryBuilder.h"
00002 #include "RecoTracker/CkfPattern/interface/TrajectorySegmentBuilder.h"
00003 
00004 
00005 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00006 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
00007 
00008 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00009 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00010 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
00011 #include "RecoTracker/CkfPattern/interface/GroupedTrajCandLess.h"
00012 #include "TrackingTools/TrajectoryFiltering/interface/RegionalTrajectoryFilter.h"
00013 #include "TrackingTools/PatternTools/interface/TempTrajectory.h"
00014 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00015 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00016 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00017 #include "TrackingTools/DetLayers/interface/DetGroup.h"
00018 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
00019 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00020 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
00021 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00022 
00023 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
00024 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00025 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00026 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
00027 #include "TrackingTools/TrajectoryState/interface/BasicSingleTrajectoryState.h"
00028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00029 #include "TrackingTools/PatternTools/interface/TransverseImpactPointExtrapolator.h"
00030 
00031 // only included for RecHit comparison operator:
00032 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
00033 
00034 #include <algorithm> 
00035 
00036 using namespace std;
00037 
00038 //#define DBG_GCTB
00039 //#define DBG2_GCTB
00040 
00041 //#define STANDARD_INTERMEDIARYCLEAN
00042 
00043 #ifdef STANDARD_INTERMEDIARYCLEAN
00044 #include "RecoTracker/CkfPattern/interface/IntermediateTrajectoryCleaner.h"
00045 #endif
00046 
00047 /* ====== B.M. to be ported layer ===========
00048 #ifdef DBG_GCTB
00049 #include "RecoTracker/CkfPattern/src/ShowCand.h"
00050 #endif
00051 // #define DBG2_GCTB
00052 #ifdef DBG2_GCTB
00053 #include "RecoTracker/CkfPattern/src/SimIdPrinter.h"
00054 #include "Tracker/TkDebugTools/interface/LayerFinderByDet.h"
00055 #include "Tracker/TkLayout/interface/TkLayerName.h"
00056 #endif
00057 =================================== */
00058 
00059 
00060 GroupedCkfTrajectoryBuilder::
00061 GroupedCkfTrajectoryBuilder(const edm::ParameterSet&              conf,
00062                             const TrajectoryStateUpdator*         updator,
00063                             const Propagator*                     propagatorAlong,
00064                             const Propagator*                     propagatorOpposite,
00065                             const Chi2MeasurementEstimatorBase*   estimator,
00066                             const TransientTrackingRecHitBuilder* recHitBuilder,
00067                             const MeasurementTracker*             measurementTracker,
00068                             const TrajectoryFilter*               filter):
00069 
00070   BaseCkfTrajectoryBuilder(conf,
00071                            updator, propagatorAlong,propagatorOpposite,
00072                            estimator, recHitBuilder, measurementTracker,filter)
00073 {
00074   // fill data members from parameters (eventually data members could be dropped)
00075   //
00076   theMaxCand                  = conf.getParameter<int>("maxCand");
00077 
00078   theLostHitPenalty           = conf.getParameter<double>("lostHitPenalty");
00079   theFoundHitBonus            = conf.getParameter<double>("foundHitBonus");
00080   theIntermediateCleaning     = conf.getParameter<bool>("intermediateCleaning");
00081   theAlwaysUseInvalid         = conf.getParameter<bool>("alwaysUseInvalidHits");
00082   theLockHits                 = conf.getParameter<bool>("lockHits");
00083   theBestHitOnly              = conf.getParameter<bool>("bestHitOnly");
00084   theMinNrOf2dHitsForRebuild  = 2;
00085   theRequireSeedHitsInRebuild = conf.getParameter<bool>("requireSeedHitsInRebuild");
00086   theMinNrOfHitsForRebuild    = max(0,conf.getParameter<int>("minNrOfHitsForRebuild"));
00087 
00088   /* ======= B.M. to be ported later =======
00089   bool setOK = thePropagator->setMaxDirectionChange(1.6);
00090   if (!setOK) 
00091     cout  << "GroupedCkfTrajectoryBuilder WARNING: "
00092           << "propagator does not support setMaxDirectionChange" 
00093           << endl;
00094   //   addStopCondition(theMinPtStopCondition);
00095   theConfigurableCondition = createAlgo<TrajectoryFilter>(componentConfig("StopCondition"));
00096   ===================================== */
00097 
00098 }
00099 
00100 
00101 void GroupedCkfTrajectoryBuilder::setEvent(const edm::Event& event) const
00102 {
00103   theMeasurementTracker->update(event);
00104 }
00105 
00106 GroupedCkfTrajectoryBuilder::TrajectoryContainer 
00107 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed) const 
00108 {
00109   TrajectoryContainer ret; 
00110   ret.reserve(10);
00111   buildTrajectories(seed, ret, 0);
00112   return ret; 
00113 }
00114 
00115 GroupedCkfTrajectoryBuilder::TrajectoryContainer 
00116 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed, 
00117                                            const TrackingRegion& region) const
00118 {
00119   TrajectoryContainer ret; 
00120   ret.reserve(10);
00121   RegionalTrajectoryFilter regionalCondition(region);
00122   buildTrajectories(seed, ret, &regionalCondition);
00123   return ret; 
00124 }
00125 
00126 void 
00127 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed, GroupedCkfTrajectoryBuilder::TrajectoryContainer &ret) const 
00128 {
00129   buildTrajectories(seed,ret,0);
00130 }
00131 
00132 void
00133 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed, 
00134                                             GroupedCkfTrajectoryBuilder::TrajectoryContainer &ret,
00135                                             const TrackingRegion& region) const
00136 {
00137   RegionalTrajectoryFilter regionalCondition(region);
00138   buildTrajectories(seed,ret,&regionalCondition);
00139 }
00140 
00141 void  
00142 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const TrajectorySeed& seed,
00143                                                   TrajectoryContainer& result) const {    
00144   TempTrajectory startingTraj = createStartingTrajectory( seed);
00145   TempTrajectoryContainer work;
00146 
00147   TrajectoryContainer final;
00148 
00149   work.reserve(result.size());
00150   for (TrajectoryContainer::iterator traj=result.begin();
00151        traj!=result.end(); ++traj) {
00152     if(traj->isValid()) work.push_back(TempTrajectory(*traj));
00153   }
00154 
00155   rebuildSeedingRegion(startingTraj,work);
00156   final.reserve(work.size());
00157 
00158   for (TempTrajectoryContainer::iterator traj=work.begin();
00159        traj!=work.end(); ++traj) {
00160     final.push_back(traj->toTrajectory());
00161   }
00162   
00163   result.swap(final);
00164   
00165 }
00166 
00167 void
00168 GroupedCkfTrajectoryBuilder::buildTrajectories (const TrajectorySeed& seed,
00169                                                 GroupedCkfTrajectoryBuilder::TrajectoryContainer &result,
00170                                                 const TrajectoryFilter* regionalCondition) const
00171 {
00172 
00173   analyseSeed( seed);
00174 
00175   TempTrajectory startingTraj = createStartingTrajectory( seed);
00176 
00177   work_.clear();
00178   groupedLimitedCandidates( startingTraj, regionalCondition, theForwardPropagator, work_);
00179   if ( work_.empty() )  return ;
00180 
00181 
00182 
00183   /*  rebuilding is de-coupled from standard building
00184   //
00185   // try to additional hits in the seeding region
00186   //
00187   if ( theMinNrOfHitsForRebuild>0 ) {
00188     // reverse direction
00189     //thePropagator->setPropagationDirection(oppositeDirection(seed.direction()));
00190     // rebuild part of the trajectory
00191     rebuildSeedingRegion(startingTraj,work);
00192   }
00193 
00194   */
00195 
00196   result.reserve(work_.size());
00197   for (TempTrajectoryContainer::const_iterator it = work_.begin(), ed = work_.end(); it != ed; ++it) {
00198       result.push_back( it->toTrajectory() );
00199   }
00200 
00201   work_.clear(); 
00202   if (work_.capacity() > work_MaxSize_) {  TempTrajectoryContainer().swap(work_); work_.reserve(work_MaxSize_/2); }
00203 
00204   analyseResult(result);
00205 
00206 #ifdef DBG_GCTB
00207   cout << "GroupedCkfTrajectoryBuilder: returning result of size " << result.size() << endl;
00208 #endif
00209 }
00210 
00211 
00212 
00213 std::string dumpCandidates(const GroupedCkfTrajectoryBuilder::TempTrajectoryContainer & candidates){
00214   std::stringstream buffer;
00215   uint ic=0;
00216   for (GroupedCkfTrajectoryBuilder::TempTrajectoryContainer::const_iterator traj=candidates.begin();
00217        traj!=candidates.end(); traj++) {  
00218     buffer<<ic++<<"] ";
00219     if (!traj->measurements().empty()){
00220       const TrajectoryMeasurement & last = traj->lastMeasurement();
00221       const TrajectoryStateOnSurface & tsos = last.updatedState();
00222       buffer<<"with: "<<traj->measurements().size()<<" measurements. Last state\n x: "<<tsos.globalPosition()<<"\n p: "<<tsos.globalMomentum()<<"\n";
00223     }
00224     else{
00225       buffer<<" no measurement. \n";}
00226   }
00227   return buffer.str();
00228 }
00229 std::string dumpCandidates(const GroupedCkfTrajectoryBuilder::TrajectoryContainer & candidates){
00230   std::stringstream buffer;
00231   uint ic=0;
00232   for (GroupedCkfTrajectoryBuilder::TrajectoryContainer::const_iterator traj=candidates.begin();
00233        traj!=candidates.end(); traj++) {  
00234     buffer<<ic++<<"] ";
00235     if (!traj->measurements().empty()){
00236       const TrajectoryMeasurement & last = traj->lastMeasurement();
00237       const TrajectoryStateOnSurface & tsos = last.updatedState();
00238       buffer<<"with: "<<traj->measurements().size()<<" measurements. Last state\n x: "<<tsos.globalPosition()<<"\n p: "<<tsos.globalMomentum()<<"\n";
00239     }
00240     else{
00241       buffer<<" no measurement. \n";}
00242   }
00243   return buffer.str();
00244 }
00245 
00246 void 
00247 GroupedCkfTrajectoryBuilder::groupedLimitedCandidates (TempTrajectory& startingTraj, 
00248                                                        const TrajectoryFilter* regionalCondition,
00249                                                        const Propagator* propagator, 
00250                                                        TempTrajectoryContainer& result) const
00251 {
00252   uint nIter=1;
00253   TempTrajectoryContainer candidates;
00254   TempTrajectoryContainer newCand;
00255   candidates.push_back( startingTraj);
00256 
00257   while ( !candidates.empty()) {
00258 #ifdef DBG_GCTB
00259     cout << "===== GCTB::groupedLimitedCandidates, start NEW iteration of WHILE loop" << endl;
00260 #endif
00261     newCand.clear();
00262     for (TempTrajectoryContainer::iterator traj=candidates.begin();
00263          traj!=candidates.end(); traj++) {
00264       if ( !advanceOneLayer(*traj,regionalCondition, propagator, newCand,result) ) {
00265 #ifdef DBG_GCTB
00266         cout << "GCTB: terminating after advanceOneLayer==false" << endl;
00267 #endif
00268         continue;
00269       }
00270     
00271 #ifdef DBG_GCTB
00272       cout << "newCand(1)";
00273       for ( TempTrajectoryContainer::const_iterator it=newCand.begin();
00274             it!=newCand.end(); it++ ) 
00275         cout << " " << it->lostHits() << " " << it->foundHits() 
00276              << " " << it->chiSquared() << " ;";
00277       cout << endl;
00278 //       cout << "newCand.size() = " << newCand.size() << endl;
00279 #endif
00280       if ((int)newCand.size() > theMaxCand) {
00281 #ifdef DBG_GCTB
00282         //ShowCand()(newCand);
00283 #endif
00284         sort( newCand.begin(), newCand.end(), GroupedTrajCandLess(theLostHitPenalty,theFoundHitBonus));
00285         newCand.erase( newCand.begin()+theMaxCand, newCand.end());
00286       }
00287 #ifdef DBG_GCTB
00288       cout << "newCand(2)";
00289       for ( TempTrajectoryContainer::const_iterator it=newCand.begin();
00290             it!=newCand.end(); it++ ) 
00291         cout << " " << it->lostHits() << " " << it->foundHits() 
00292              << " " << it->chiSquared() << " ;";
00293       cout << endl;
00294 #endif
00295     }
00296 
00297 #ifdef DBG_GCTB
00298     cout << "newCand.size() at end = " << newCand.size() << endl;
00299 #endif
00300 /*
00301     if (theIntermediateCleaning) {
00302       candidates.clear();
00303       candidates = groupedIntermediaryClean(newCand);
00304     } else {
00305       candidates.swap(newCand);
00306     }
00307 */
00308     if (theIntermediateCleaning) {
00309 #ifdef STANDARD_INTERMEDIARYCLEAN
00310         IntermediateTrajectoryCleaner::clean(newCand);  
00311 #else 
00312         groupedIntermediaryClean(newCand);
00313 #endif  
00314 
00315     }   
00316     candidates.swap(newCand);
00317 
00318     LogDebug("CkfPattern") <<result.size()<<" candidates after "<<nIter++<<" groupedCKF iteration: \n"
00319                            <<dumpCandidates(result)
00320                            <<"\n "<<candidates.size()<<" running candidates are: \n"
00321                            <<dumpCandidates(candidates);
00322 
00323 #ifdef DBG_GCTB
00324     cout << "candidates(3)";
00325     for ( TempTrajectoryContainer::const_iterator it=candidates.begin();
00326           it!=candidates.end(); it++ ) 
00327       cout << "lost,found,chi2, last pt, r,z: " 
00328            << it->lostHits() << " , " 
00329            << it->foundHits() << " , " 
00330            << it->chiSquared() << " , "
00331            << it->lastMeasurement().updatedState().globalMomentum().perp() << " , "
00332            << it->lastMeasurement().updatedState().globalPosition().perp() << " , "
00333            << it->lastMeasurement().updatedState().globalPosition().z() << endl; 
00334     cout << endl;
00335 
00336     cout << "after intermediate cleaning = " << candidates.size() << endl;
00337     //B.M. ShowCand()(candidates);
00338     cout << "===== GCTB::groupedLimitedCandidates, END iteration of WHILE loop" << endl;
00339 #endif
00340   }
00341 }
00342 
00343 bool 
00344 GroupedCkfTrajectoryBuilder::advanceOneLayer (TempTrajectory& traj, 
00345                                               const TrajectoryFilter* regionalCondition, 
00346                                               const Propagator* propagator,
00347                                               TempTrajectoryContainer& newCand, 
00348                                               TempTrajectoryContainer& result) const
00349 {
00350   std::pair<TSOS,std::vector<const DetLayer*> > stateAndLayers = findStateAndLayers(traj);
00351   vector<const DetLayer*>::iterator layerBegin = stateAndLayers.second.begin();
00352   vector<const DetLayer*>::iterator layerEnd   = stateAndLayers.second.end();
00353 
00354   //   if (nl.empty()) {
00355   //     addToResult(traj,result);
00356   //     return false;
00357   //   }
00358   
00359 #ifdef DBG_GCTB
00360   vector<const DetLayer*> & nl = stateAndLayers.second;
00361   #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00362   #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00363   //B.M. TkLayerName layerName;
00364   //B.M. cout << "Started from " << layerName(traj.lastLayer()) 
00365   const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
00366   const ForwardDetLayer* sfdl = dynamic_cast<const ForwardDetLayer*>(traj.lastLayer());
00367   if (sbdl)     cout << "Started from " << traj.lastLayer() << " r " << sbdl->specificSurface().radius() << endl;
00368   if (sfdl) cout << "Started from " << traj.lastLayer() << " z " << sfdl->specificSurface().position().z() << endl;
00369   cout << "Trying to go to";
00370   for ( vector<const DetLayer*>::iterator il=nl.begin();
00371         il!=nl.end(); il++){ 
00372     //B.M. cout << " " << layerName(*il)  << " " << *il << endl;
00373     const BarrelDetLayer* bdl = dynamic_cast<const BarrelDetLayer*>(*il);
00374     const ForwardDetLayer* fdl = dynamic_cast<const ForwardDetLayer*>(*il);
00375 
00376     if (bdl) cout << " r " << bdl->specificSurface().radius() << endl;
00377     if (fdl) cout << " z " << fdl->specificSurface().position().z() << endl;
00378     //cout << " " << *il << endl;   
00379   }
00380   cout << endl;
00381 #endif
00382 
00383   bool foundSegments(false);
00384   bool foundNewCandidates(false);
00385   for ( vector<const DetLayer*>::iterator il=layerBegin; 
00386         il!=layerEnd; il++) {
00387 
00388     TSOS stateToUse = stateAndLayers.first;
00389     if ((*il)==traj.lastLayer())
00390       {
00391         LogDebug("CkfPattern")<<" self propagating in advanceOneLayer.\n from: \n"<<stateToUse;
00392         //self navigation case
00393         // go to a middle point first
00394         TransverseImpactPointExtrapolator middle;
00395         GlobalPoint center(0,0,0);
00396         stateToUse = middle.extrapolate(stateToUse, center, *theForwardPropagator);
00397         
00398         if (!stateToUse.isValid()) continue;
00399         LogDebug("CkfPattern")<<"to: "<<stateToUse;
00400       }
00401 
00402     TrajectorySegmentBuilder layerBuilder(theMeasurementTracker,
00403                                           theLayerMeasurements,
00404                                           **il,*propagator,
00405                                           *theUpdator,*theEstimator,
00406                                           theLockHits,theBestHitOnly);
00407 
00408 #ifdef DBG_GCTB
00409     cout << "GCTB: starting from r / z = " << stateToUse.globalPosition().perp()
00410      << " / " << stateToUse.globalPosition().z() << " , pt / pz = "
00411      << stateToUse.globalMomentum().perp() << " / "
00412      << stateToUse.globalMomentum().z() << " for layer at "
00413      << *il << endl;
00414     cout << "     errors:";
00415     for ( int i=0; i<5; i++ )  cout << " " << sqrt(stateToUse.curvilinearError().matrix()(i,i));
00416     cout << endl;
00417 
00418     //cout << "GCTB: starting from r / phi / z = " << stateAndLayers.first.globalPosition().perp()
00419          //<< " / " << stateAndLayers.first.globalPosition().phi()
00420          //<< " / " << stateAndLayers.first.globalPosition().z() << " , pt / pz = " 
00421          //<< stateAndLayers.first.globalMomentum().perp() << " / " 
00422          //<< stateAndLayers.first.globalMomentum().z() << " for layer at "
00423          //<< *il << endl;
00424     //cout << "     errors:";
00425     //for ( int i=0; i<5; i++ )  cout << " " << sqrt(stateAndLayers.first.curvilinearError().matrix()(i,i));
00426     //cout << endl;
00427 #endif
00428 
00429     TempTrajectoryContainer segments=
00430       //layerBuilder.segments(stateAndLayers.first);
00431       layerBuilder.segments(stateToUse);
00432 
00433 #ifdef DBG_GCTB
00434     cout << "GCTB: number of segments = " << segments.size() << endl;
00435 #endif
00436 
00437     if ( !segments.empty() )  foundSegments = true;
00438 
00439     for ( TempTrajectoryContainer::const_iterator is=segments.begin();
00440           is!=segments.end(); is++ ) {
00441       //
00442       // assume "invalid hit only" segment is last in list
00443       //
00444       const TempTrajectory::DataContainer & measurements = is->measurements();
00445       if ( !theAlwaysUseInvalid && is!=segments.begin() && measurements.size()==1 && 
00446            (measurements.front().recHit()->getType() == TrackingRecHit::missing) )  break;
00447       //
00448       // create new candidate
00449       //
00450       TempTrajectory newTraj(traj);
00451       
00452       newTraj.push(*is);
00453       //GIO// for ( vector<TM>::const_iterator im=measurements.begin();
00454       //GIO//        im!=measurements.end(); im++ )  newTraj.push(*im);
00455       //if ( toBeContinued(newTraj,regionalCondition) ) { TOBE FIXED
00456       if ( toBeContinued(newTraj) ) {
00457 
00458 #ifdef DBG_GCTB
00459         cout << "GCTB: adding new trajectory to candidates" << endl;
00460 #endif
00461 
00462         newCand.push_back(newTraj);
00463         foundNewCandidates = true;
00464       }
00465       else {
00466 
00467 #ifdef DBG_GCTB
00468         cout << "GCTB: adding new trajectory to results" << endl;
00469 #endif
00470 
00471         addToResult(newTraj,result);
00472       }
00473     }
00474   }
00475 
00476 #ifdef DBG_GCTB
00477   if ( !foundSegments )  cout << "GCTB: adding input trajectory to result" << endl;
00478 #endif
00479 
00480   if ( !foundSegments )  addToResult(traj,result);
00481   return foundNewCandidates;
00482 }
00483 
00484 //TempTrajectoryContainer
00485 void
00486 GroupedCkfTrajectoryBuilder::groupedIntermediaryClean (TempTrajectoryContainer& theTrajectories) const 
00487 {
00488   //if (theTrajectories.empty()) return TrajectoryContainer();
00489   //TrajectoryContainer result;
00490   if (theTrajectories.empty()) return;  
00491   //RecHitEqualByChannels recHitEqualByChannels(false, false);
00492   int firstLayerSize, secondLayerSize;
00493   vector<const DetLayer*> firstLayers, secondLayers;
00494 
00495   for (TempTrajectoryContainer::iterator firstTraj=theTrajectories.begin();
00496        firstTraj!=(theTrajectories.end()-1); firstTraj++) {
00497 
00498     if ( (!firstTraj->isValid()) ||
00499          (!firstTraj->lastMeasurement().recHit()->isValid()) ) continue;
00500     const TempTrajectory::DataContainer & firstMeasurements = firstTraj->measurements();
00501     layers(firstMeasurements, firstLayers);
00502     firstLayerSize = firstLayers.size();
00503     if ( firstLayerSize<4 )  continue;
00504 
00505     for (TempTrajectoryContainer::iterator secondTraj=(firstTraj+1);
00506        secondTraj!=theTrajectories.end(); secondTraj++) {
00507 
00508       if ( (!secondTraj->isValid()) ||
00509            (!secondTraj->lastMeasurement().recHit()->isValid()) ) continue;
00510       const TempTrajectory::DataContainer & secondMeasurements = secondTraj->measurements();
00511       layers(secondMeasurements, secondLayers);
00512       secondLayerSize = secondLayers.size();
00513       //
00514       // only candidates using the same last 3 layers are compared
00515       //
00516       if ( firstLayerSize!=secondLayerSize )  continue;
00517       if ( firstLayers[0]!=secondLayers[0] ||
00518            firstLayers[1]!=secondLayers[1] ||
00519            firstLayers[2]!=secondLayers[2] )  continue;
00520 
00521       TempTrajectory::DataContainer::const_iterator im1 = firstMeasurements.rbegin();
00522       TempTrajectory::DataContainer::const_iterator im2 = secondMeasurements.rbegin();
00523       //
00524       // check for identical hits in the last layer
00525       //
00526       bool unequal(false);
00527       const DetLayer* layerPtr = firstLayers[0];
00528       while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
00529         if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr )  break;
00530         if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
00532              !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
00533           unequal = true;
00534           break;
00535         }
00536         --im1;
00537         --im2;
00538       }
00539       if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
00540            im1->layer()==layerPtr || im2->layer()==layerPtr || unequal )  continue;
00541       //
00542       // check for invalid hits in the layer -2
00543       // compare only candidates with invalid / valid combination
00544       //
00545       layerPtr = firstLayers[1];
00546       bool firstValid(true);
00547       while ( im1!=firstMeasurements.rend()&&im1->layer()==layerPtr ) {
00548         if ( !im1->recHit()->isValid() )  firstValid = false;
00549         --im1;
00550       }
00551       bool secondValid(true);
00552       while ( im2!=secondMeasurements.rend()&&im2->layer()==layerPtr ) {
00553         if ( !im2->recHit()->isValid() )  secondValid = false;
00554         --im2;
00555       }
00556       if ( !tkxor(firstValid,secondValid) )  continue;
00557       //
00558       // ask for identical hits in layer -3
00559       //
00560       unequal = false;
00561       layerPtr = firstLayers[2];
00562       while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
00563         if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr )  break;
00564         if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
00566              !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
00567           unequal = true;
00568           break;
00569         }
00570         --im1;
00571         --im2;
00572       }
00573       if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
00574            im1->layer()==layerPtr || im2->layer()==layerPtr || unequal )  continue;
00575 
00576       if ( !firstValid ) {
00577         firstTraj->invalidate();
00578         break;
00579       }
00580       else {
00581         secondTraj->invalidate();
00582         break;
00583       }
00584     }
00585   }
00586 /*
00587   for (TempTrajectoryContainer::const_iterator it = theTrajectories.begin();
00588        it != theTrajectories.end(); it++) {
00589     if(it->isValid()) result.push_back( *it);
00590   }
00591 
00592   return result;
00593 */
00594   theTrajectories.erase(std::remove_if( theTrajectories.begin(),theTrajectories.end(),
00595                                         std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
00596  //                                     boost::bind(&TempTrajectory::isValid,_1)), 
00597                         theTrajectories.end());
00598 }
00599 
00600 void
00601 GroupedCkfTrajectoryBuilder::layers (const TempTrajectory::DataContainer& measurements,
00602                                      vector<const DetLayer*> &result) const 
00603 {
00604   result.clear();
00605 
00606   if ( measurements.empty() )  return ;
00607 
00608   result.push_back(measurements.back().layer());
00609   TempTrajectory::DataContainer::const_iterator ifirst = measurements.rbegin();
00610   --ifirst;      
00611   for ( TempTrajectory::DataContainer::const_iterator im=ifirst;
00612         im!=measurements.rend(); --im ) {
00613     if ( im->layer()!=result.back() )  result.push_back(im->layer());
00614   }
00615 #ifdef DBG2_GCTB
00616   for (vector<const DetLayer*>::const_iterator iter = result.begin(); iter != result.end(); iter++){
00617         if (!*iter) cout << "Warning: null det layer!! " << endl;
00618   }
00619 #endif
00620 }
00621 
00622 void
00623 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(TempTrajectory& startingTraj,
00624                                                   TempTrajectoryContainer& result) const
00625 {
00626   //
00627   // Rebuilding of trajectories. Candidates are taken from result,
00628   // which will be replaced with the solutions after rebuild
00629   // (assume vector::swap is more efficient than building new container)
00630   //
00631 #ifdef DBG2_GCTB
00632   cout << "Starting to rebuild " << result.size() << " tracks" << endl;
00633 #endif
00634   //
00635   // Fitter (need to create it here since the propagation direction
00636   // might change between different starting trajectories)
00637   //
00638   KFTrajectoryFitter fitter(*theBackwardPropagator,updator(),estimator());
00639   //
00640   TempTrajectoryContainer reFitted;
00641   TrajectorySeed::range rseedHits = startingTraj.seed().recHits();
00642   std::vector<const TrackingRecHit*> seedHits;
00643   //seedHits.insert(seedHits.end(), rseedHits.first, rseedHits.second);
00644   //for (TrajectorySeed::recHitContainer::const_iterator iter = rseedHits.first; iter != rseedHits.second; iter++){
00645   //    seedHits.push_back(&*iter);
00646   //}
00647 
00648   //unsigned int nSeed(seedHits.size());
00649   unsigned int nSeed(rseedHits.second-rseedHits.first);
00650   //seedHits.reserve(nSeed);
00651   TempTrajectoryContainer rebuiltTrajectories;
00652   for ( TempTrajectoryContainer::iterator it=result.begin();
00653         it!=result.end(); it++ ) {
00654     //
00655     // skip candidates which are not exceeding the seed size
00656     // (should not happen) - keep existing trajectory
00657     //
00658     if ( it->measurements().size()<=startingTraj.measurements().size() ) {
00659       rebuiltTrajectories.push_back(*it);
00660       #ifdef DBG2_GCTB
00661       cout << " candidates not exceeding the seed size; skipping " <<  endl;
00662       #endif
00663       continue;
00664     }
00665     //
00666     // Refit - keep existing trajectory in case fit is not possible
00667     // or fails
00668     //
00669     backwardFit(*it,nSeed,fitter,reFitted,seedHits);
00670     if ( reFitted.size()!=1 ) {
00671       rebuiltTrajectories.push_back(*it);
00672       //std::cout << "after reFitted.size() " << reFitted.size() << std::endl;
00673       continue;
00674     }
00675     //std::cout << "after reFitted.size() " << reFitted.size() << std::endl;
00676     //
00677     // Rebuild seeding part. In case it fails: keep initial trajectory
00678     // (better to drop it??)
00679     //
00680     int nRebuilt =
00681       rebuildSeedingRegion (seedHits,reFitted.front(),rebuiltTrajectories);
00682     if ( nRebuilt==0 )  rebuiltTrajectories.push_back(*it);
00683   }
00684   //
00685   // Replace input trajectories with new ones
00686   //
00687   result.swap(rebuiltTrajectories);
00688 }
00689 
00690 int
00691 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const std::vector<const TrackingRecHit*>& seedHits, 
00692                                                   TempTrajectory& candidate,
00693                                                   TempTrajectoryContainer& result) const 
00694 {
00695   //
00696   // Try to rebuild one candidate in the seeding region.
00697   // The resulting trajectories are returned in result,
00698   // the count is the return value.
00699   //
00700   TempTrajectoryContainer rebuiltTrajectories;
00701 #ifdef DBG2_GCTB
00702 /*  const LayerFinderByDet layerFinder;
00703   if ( !seedHits.empty() && seedHits.front().isValid() ) {
00704     DetLayer* seedLayer = layerFinder(seedHits.front().det());
00705     cout << "Seed hit at " << seedHits.front().globalPosition()
00706          << " " << seedLayer << endl;
00707     cout << "Started from " 
00708          << candidate.lastMeasurement().updatedState().globalPosition().perp() << " "
00709          << candidate.lastMeasurement().updatedState().globalPosition().z() << endl;
00710     pair<bool,TrajectoryStateOnSurface> layerComp(false,TrajectoryStateOnSurface());
00711     if ( seedLayer ) layerComp =
00712       seedLayer->compatible(candidate.lastMeasurement().updatedState(),
00713                               propagator(),estimator());
00714     pair<bool,TrajectoryStateOnSurface> detComp =
00715       seedHits.front().det().compatible(candidate.lastMeasurement().updatedState(),
00716                                         propagator(),estimator());
00717     cout << "  layer compatibility = " << layerComp.first;
00718     cout << "  det compatibility = " << detComp.first;
00719     if ( detComp.first ) {
00720       cout << "  estimate = " 
00721            << estimator().estimate(detComp.second,seedHits.front()).second ;
00722     }
00723     cout << endl;
00724   }*/
00725   cout << "Before backward building: #measurements = " 
00726        << candidate.measurements().size() ; //<< endl;;
00727 #endif
00728   //
00729   // Use standard building with standard cuts. Maybe better to use different
00730   // cuts from "forward" building (e.g. no check on nr. of invalid hits)?
00731   //
00732   groupedLimitedCandidates(candidate,(const TrajectoryFilter*)0, theBackwardPropagator, rebuiltTrajectories);
00733 #ifdef DBG2_GCTB
00734   cout << "   After backward building: #measurements =";
00735   for ( TempTrajectoryContainer::iterator it=rebuiltTrajectories.begin();
00736         it!=rebuiltTrajectories.end(); it++ )  cout << " " << it->measurements().size();
00737   cout << endl;
00738 #endif
00739   //
00740   // Check & count resulting candidates
00741   //
00742   int nrOfTrajectories(0);
00743   //const RecHitEqualByChannels recHitEqual(false,false);
00744   //vector<TM> oldMeasurements(candidate.measurements());
00745   for ( TempTrajectoryContainer::iterator it=rebuiltTrajectories.begin();
00746         it!=rebuiltTrajectories.end(); it++ ) {
00747 
00748     TempTrajectory::DataContainer newMeasurements(it->measurements());
00749     //
00750     // Verify presence of seeding hits?
00751     //
00752     if ( theRequireSeedHitsInRebuild ) {
00753       // no hits found (and possibly some invalid hits discarded): drop track
00754       if ( newMeasurements.size()<=candidate.measurements().size() ){  
00755 #ifdef DBG2_GCTB
00756         cout << "newMeasurements.size()<=candidate.measurements().size()" << endl;
00757 #endif
00758         continue;
00759       } 
00760       // verify presence of hits
00761       //GIO//if ( !verifyHits(newMeasurements.begin()+candidate.measurements().size(),
00762       //GIO//                  newMeasurements.end(),seedHits) ){
00763       if ( !verifyHits(newMeasurements.rbegin(), 
00764                        newMeasurements.size() - candidate.measurements().size(),
00765                        seedHits) ){
00766 #ifdef DBG2_GCTB
00767           cout << "seed hits not found in rebuild" << endl;     
00768 #endif  
00769           continue; 
00770       }
00771     }
00772     //
00773     // construct final trajectory in the right order
00774     //
00775     TempTrajectory reversedTrajectory(it->seed(),it->seed().direction());
00776     for (TempTrajectory::DataContainer::const_iterator im=newMeasurements.rbegin(), ed = newMeasurements.rend();
00777           im != ed; --im ) {
00778       reversedTrajectory.push(*im);
00779     }
00780     // save & count result
00781     result.push_back(reversedTrajectory);
00782     nrOfTrajectories++;
00783 #ifdef DBG2_GCTB
00784     cout << "New traj direction = " << reversedTrajectory.direction() << endl;
00785     cmsutils::bqueue<TM> tms = reversedTrajectory.measurements();
00786     for (cmsutils::bqueue<TM>::const_iterator im=tms.rbegin(),end=tms.rend();
00787          im!=end; --im ) {
00788       if ( im->recHit()->isValid() )  cout << im->recHit()->globalPosition();
00789       else cout << "(-,-,-)";
00790       cout << " ";
00791       cout << " fwdPred " << im->forwardPredictedState().isValid();
00792       cout << " bwdPred " << im->backwardPredictedState().isValid();
00793       cout << " upPred " << im->updatedState().isValid();
00794       //SimIdPrinter()(im->recHit());
00795       cout << endl;
00796     }
00797 #endif
00798   }
00799   return nrOfTrajectories;
00800 }
00801 
00802 void
00803 GroupedCkfTrajectoryBuilder::backwardFit (TempTrajectory& candidate, unsigned int nSeed,
00804                                                     const TrajectoryFitter& fitter,
00805                                                     TempTrajectoryContainer& fittedTracks,
00806                                                     std::vector<const TrackingRecHit*>& remainingHits) const
00807 {
00808   //
00809   // clear array of non-fitted hits
00810   //
00811   remainingHits.clear();
00812   fittedTracks.clear();
00813   //
00814   // skip candidates which are not exceeding the seed size
00815   // (should not happen)
00816   //
00817   if ( candidate.measurements().size()<=nSeed ) {
00818     fittedTracks.clear();
00819     return;
00820   }
00821 #ifdef DBG2_GCTB
00822     {
00823       cout << "nSeed " << nSeed << endl;
00824       cout << "Old traj direction = " << candidate.direction() << endl;
00825       cmsutils::bqueue<TM> tms = candidate.measurements();
00826       for (cmsutils::bqueue<TM>::const_iterator im=tms.rbegin(),end=tms.rend();
00827            im!=end; --im ) {
00828         if ( im->recHit()->isValid() )  cout << im->recHit()->globalPosition();
00829         else cout << "(-,-,-)";
00830         cout << " layer " << im->layer();
00831         cout << " fwdPred " << im->forwardPredictedState().isValid();
00832         cout << " bwdPred " << im->backwardPredictedState().isValid();
00833         cout << " upPred " << im->updatedState().isValid() << " ;";
00834         //SimIdPrinter()(im->recHit());
00835         cout << endl;
00836       }
00837     }
00838 #endif
00839   //
00840   // backward fit trajectory (excluding the seeding region)
00841   //
00842   TempTrajectory::DataContainer oldMeasurements(candidate.measurements());
00843 //   int nOld(oldMeasurements.size());
00844 //   const unsigned int nHitAllMin(5);
00845 //   const unsigned int nHit2dMin(2);
00846   unsigned int nHit(0);    // number of valid hits after seeding region
00847   //unsigned int nHit2d(0);  // number of valid hits after seeding region with 2D info
00848   // use all hits except the first n (from seed), but require minimum
00849   // specified in configuration.
00850   //unsigned int nHitMin = max(oldMeasurements.size()-nSeed,theMinNrOfHitsForRebuild);
00851   unsigned int nHitMin = oldMeasurements.size()-nSeed;
00852   // we want to rebuild only if the number of measurements excluding the seed measurements is higher than the cut
00853   if (nHitMin<theMinNrOfHitsForRebuild){
00854         fittedTracks.clear();
00855         return;
00856   }
00857   //cout << "nHitMin " << nHitMin << endl;
00858 #ifdef DBG2_GCTB
00859   cout << "Sizes: " << oldMeasurements.size() << " / " << endl;
00860 #endif
00861   //
00862   // create input trajectory for backward fit
00863   //
00864   Trajectory fwdTraj(candidate.seed(),oppositeDirection(candidate.direction()));
00865   //const TrajectorySeed seed = TrajectorySeed(PTrajectoryStateOnDet(), TrajectorySeed::recHitContainer(), oppositeDirection(candidate.direction()));
00866   //Trajectory fwdTraj(seed, oppositeDirection(candidate.direction()));
00867   std::vector<const DetLayer*> bwdDetLayer; 
00868   for ( TempTrajectory::DataContainer::const_iterator im=oldMeasurements.rbegin();
00869         im!=oldMeasurements.rend(); --im) {
00870     const TrackingRecHit* hit = im->recHit()->hit();
00871     //
00872     // add hits until required number is reached
00873     //
00874     if ( nHit<nHitMin ){//|| nHit2d<theMinNrOf2dHitsForRebuild ) {
00875       fwdTraj.push(*im);
00876       bwdDetLayer.push_back(im->layer());
00877       //
00878       // count valid / 2D hits
00879       //
00880       if ( hit->isValid() ) {
00881         nHit++;
00882         //if ( hit.isMatched() ||
00883         //     hit.det().detUnits().front()->type().module()==pixel )
00884         //nHit2d++;
00885       }
00886     }
00887     //if (nHit==nHitMin) lastBwdDetLayer=im->layer();   
00888     //
00889     // keep remaining (valid) hits for verification
00890     //
00891     else if ( hit->isValid() ) {
00892       //std::cout << "Adding a remaining hit" << std::endl;
00893       remainingHits.push_back(hit);
00894     }
00895   }
00896   //
00897   // Fit only if required number of valid hits can be used
00898   //
00899   if ( nHit<nHitMin ){  //|| nHit2d<theMinNrOf2dHitsForRebuild ) {
00900     fittedTracks.clear();
00901     return;
00902   }
00903   //
00904   // Do the backward fit (important: start from scaled, not random cov. matrix!)
00905   //
00906   TrajectoryStateOnSurface firstTsos(fwdTraj.firstMeasurement().updatedState());
00907   //cout << "firstTsos "<< firstTsos << endl;
00908   firstTsos.rescaleError(100.);
00909   //TrajectoryContainer bwdFitted(fitter.fit(fwdTraj.seed(),fwdTraj.recHits(),firstTsos));
00910   TrajectoryContainer bwdFitted(fitter.fit(
00911                 TrajectorySeed(PTrajectoryStateOnDet(), TrajectorySeed::recHitContainer(), oppositeDirection(candidate.direction())),
00912                 fwdTraj.recHits(),firstTsos));
00913   if (bwdFitted.size()){
00914 #ifdef DBG2_GCTB
00915         cout << "Obtained " << bwdFitted.size() << " bwdFitted trajectories with measurement size " << bwdFitted.front().measurements().size() << endl;
00916 #endif
00917         TempTrajectory fitted(fwdTraj.seed(), fwdTraj.direction());
00918         vector<TM> tmsbf = bwdFitted.front().measurements();
00919         int iDetLayer=0;
00920         //this is ugly but the TM in the fitted track do not contain the DetLayer.
00921         //So we have to cache the detLayer pointers and replug them in.
00922         //For the backward building it would be enaugh to cache the last DetLayer, 
00923         //but for the intermediary cleaning we need all
00924         for ( vector<TM>::const_iterator im=tmsbf.begin();im!=tmsbf.end(); im++ ) {
00925                 fitted.push(TM( (*im).forwardPredictedState(),
00926                                 (*im).backwardPredictedState(),
00927                                 (*im).updatedState(),
00928                                 (*im).recHit(),
00929                                 (*im).estimate(),
00930                                 bwdDetLayer[iDetLayer]));
00931 #ifdef DBG2_GCTB
00932                 if ( im->recHit()->isValid() )  cout << im->recHit()->globalPosition();
00933                 else cout << "(-,-,-)";
00934                 cout << " layer " << bwdDetLayer[iDetLayer];
00935                 cout << " fwdPred " << im->forwardPredictedState().isValid();
00936                 cout << " bwdPred " << im->backwardPredictedState().isValid();
00937                 cout << " upPred " << im->updatedState().isValid() << " ;";
00938                 //SimIdPrinter()(im->recHit());
00939                 cout << endl;   
00940 #endif          
00941                 iDetLayer++;
00942         }
00943 /*
00944         TM lastMeas = bwdFitted.front().lastMeasurement();
00945         fitted.pop();
00946         fitted.push(TM(lastMeas.forwardPredictedState(), 
00947                                lastMeas.backwardPredictedState(), 
00948                                lastMeas.updatedState(),
00949                                lastMeas.recHit(),
00950                                lastMeas.estimate(),
00951                                lastBwdDetLayer));*/
00952         fittedTracks.push_back(fitted);
00953   }
00954   //
00955   // save result
00956   //
00957   //fittedTracks.swap(bwdFitted);
00958   //cout << "Obtained " << fittedTracks.size() << " fittedTracks trajectories with measurement size " << fittedTracks.front().measurements().size() << endl;
00959 }
00960 
00961 bool
00962 GroupedCkfTrajectoryBuilder::verifyHits (TempTrajectory::DataContainer::const_iterator rbegin,
00963                                          size_t maxDepth,
00964                                          const std::vector<const TrackingRecHit*>& hits) const
00965 {
00966   //
00967   // verify presence of the seeding hits
00968   //
00969 #ifdef DBG2_GCTB
00970   cout << "Checking for " << hits.size() << " hits in "
00971        << maxDepth << " measurements" << endl;
00972 #endif
00973   TempTrajectory::DataContainer::const_iterator rend = rbegin; 
00974   while (maxDepth > 0) { --maxDepth; --rend; }
00975   for ( vector<const TrackingRecHit*>::const_iterator ir=hits.begin();
00976         ir!=hits.end(); ir++ ) {
00977     // assume that all seeding hits are valid!
00978     bool foundHit(false);
00979     for ( TempTrajectory::DataContainer::const_iterator im=rbegin; im!=rend; --im ) {
00980       if ( im->recHit()->isValid() && (*ir)->sharesInput(im->recHit()->hit(), TrackingRecHit::some) ) {
00981         foundHit = true;
00982         break;
00983       }
00984     }
00985     if ( !foundHit )  return false;
00986   }
00987   return true;
00988 }
00989 
00990 
00991 
00992 

Generated on Tue Jun 9 17:45:21 2009 for CMSSW by  doxygen 1.5.4