CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoTracker/CkfPattern/src/GroupedCkfTrajectoryBuilder.cc

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