CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoTracker/CkfPattern/src/GroupedCkfTrajectoryBuilder.cc

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