CMS 3D CMS Logo

TrajectorySegmentBuilder.cc

Go to the documentation of this file.
00001 
00002 #include "RecoTracker/CkfPattern/interface/TrajectorySegmentBuilder.h"
00003 
00004 #include "RecoTracker/CkfPattern/src/RecHitIsInvalid.h"
00005 #include "TrackingTools/PatternTools/interface/TempTrajectory.h"
00006 
00007 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00008 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00009 #include "TrackingTools/PatternTools/interface/MeasurementEstimator.h"
00010 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00011 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00012 #include "TrackingTools/MeasurementDet/interface/TrajectoryMeasurementGroup.h"
00013 #include "TrackingTools/DetLayers/interface/DetGroup.h"
00014 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00015 #include "RecoTracker/CkfPattern/src/TrajectoryLessByFoundHits.h"
00016 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
00017 #include "TrackingTools/DetLayers/interface/GeomDetCompatibilityChecker.h"
00018 #include "TrackingTools/MeasurementDet/interface/MeasurementDet.h"
00019 
00020 #include <algorithm> 
00021 
00022 // #define DBG_TSB
00023 
00024 using namespace std;
00025 
00026 TrajectorySegmentBuilder::TempTrajectoryContainer
00027 TrajectorySegmentBuilder::segments (const TSOS startingState)
00028 {
00029   //
00030   // create empty trajectory
00031   //
00032   theLockedHits.clear();
00033   TrajectorySeed invalidSeed;
00034   TempTrajectory startingTrajectory(invalidSeed,theFullPropagator.propagationDirection());
00035   //
00036   // get measurement groups
00037   //
00038   vector<TMG> measGroups = 
00039     theLayerMeasurements->groupedMeasurements(theLayer,startingState,theFullPropagator,theEstimator);
00040     //B.M. theLayer.groupedMeasurements(startingState,theFullPropagator,theEstimator);
00041 
00042 #ifdef DBG_TSB
00043   cout << "TSB: number of measurement groups = " << measGroups.size() << endl;
00044   //  theDbgFlg = measGroups.size()>1;
00045   theDbgFlg = true;
00046 #else
00047   theDbgFlg = false;
00048 #endif
00049 
00050   if ( theDbgFlg ) {
00051     int ntot(1);
00052     for (vector<TMG>::const_iterator ig=measGroups.begin();
00053          ig!=measGroups.end(); ++ig) {
00054       int ngrp(0);
00055       const vector<TM>& measurements = ig->measurements();
00056       for ( vector<TM>::const_iterator im=measurements.begin();
00057             im!=measurements.end(); ++im ) {
00058         if ( im->recHit()->isValid() )  ngrp++;
00059       }
00060       cout << " " << ngrp;
00061       if ( ngrp>0 )  ntot *= ngrp;
00062     }  
00063     cout << endl;
00064     cout << "TrajectorySegmentBuilder::partialTrajectories:: det ids & hit types / group" << endl;
00065     for (vector<TMG>::const_iterator ig=measGroups.begin();
00066          ig!=measGroups.end(); ++ig) {
00067       const vector<TM>& measurements = ig->measurements();
00068       for ( vector<TM>::const_iterator im=measurements.begin();
00069             im!=measurements.end(); ++im ) {
00070         if ( im!=measurements.begin() )  cout << " / ";
00071         if ( im->recHit()->det() )
00072           cout << im->recHit()->det()->geographicalId().rawId() << " "
00073                << im->recHit()->getType();
00074         else
00075           cout << "no det";
00076       }
00077       cout << endl;
00078     }  
00079   }
00080 
00081 #ifdef DBG_TSB
00082 //   if ( measGroups.size()>4 ) {
00083     cout << typeid(theLayer).name() << endl;
00084     cout << startingState.localError().matrix() << endl;
00085 //     for (vector<TMG>::const_iterator ig=measGroups.begin();
00086 //       ig!=measGroups.end(); ig++) {
00087 //       cout << "Nr. of measurements = " << ig->measurements().size() << endl;
00088 //       const DetGroup& dg = ig->detGroup();
00089 //       for ( DetGroup::const_iterator id=dg.begin();
00090 //          id!=dg.end(); id++ ) {
00091 //      GlobalPoint p(id->det()->position());
00092 //      GlobalVector v(id->det()->toGlobal(LocalVector(0.,0.,1.)));
00093 //      cout << p.perp() << " " << p.phi() << " " << p.z() << " ; "
00094 //           << v.phi() << " " << v.z() << endl;
00095 //       }
00096 //     }
00097 //   }
00098 #endif
00099 
00100   TempTrajectoryContainer candidates = 
00101     addGroup(startingTrajectory,measGroups.begin(),measGroups.end());
00102 
00103   if (theDbgFlg) cout << "TSB: back with " << candidates.size() << " candidates" << endl;
00104   // clean
00105   //
00106   //
00107   // add invalid hit - try to get first detector hit by the extrapolation
00108   //
00109 
00110   updateWithInvalidHit(startingTrajectory,measGroups,candidates);
00111   if (theDbgFlg) cout << "TSB: " << candidates.size() << " candidates after invalid hit" << endl;
00112   return candidates;
00113 }
00114 
00115 void TrajectorySegmentBuilder::updateTrajectory (TempTrajectory& traj,
00116                                                  const TM& tm) const
00117 {
00118   TSOS predictedState = tm.predictedState();
00119   ConstRecHitPointer hit = tm.recHit();
00120  
00121   if ( hit->isValid()) {
00122     traj.push( TM( predictedState, theUpdator.update( predictedState, *hit),
00123                    hit, tm.estimate(), tm.layer()));
00124 //     TrajectoryMeasurement tm(traj.lastMeasurement());
00125 //     if ( tm.updatedState().isValid() ) {
00126 //       if ( !hit.det().surface().bounds().inside(tm.updatedState().localPosition(),
00127 //                                              tm.updatedState().localError().positionError(),3.) ) {
00128 //      cout << "Incompatibility after update for det at " << hit.det().position() << ":" << endl;
00129 //      cout << tm.predictedState().localPosition() << " " 
00130 //           << tm.predictedState().localError().positionError() << endl;
00131 //      cout << hit.localPosition() << " " << hit.localPositionError() << endl;
00132 //      cout << tm.updatedState().localPosition() << " "
00133 //           << tm.updatedState().localError().positionError() << endl;
00134 //       }
00135 //     }
00136   }
00137   else {
00138     traj.push( TM( predictedState, hit,0, tm.layer()));
00139   }
00140 }
00141 
00142 
00143 TrajectorySegmentBuilder::TempTrajectoryContainer
00144 TrajectorySegmentBuilder::addGroup (TempTrajectory& traj,
00145                                     vector<TMG>::const_iterator begin,
00146                                     vector<TMG>::const_iterator end)
00147 {
00148   vector<TempTrajectory> ret;
00149   if ( begin==end ) {
00150     //std::cout << "TrajectorySegmentBuilder::addGroup" << " traj.empty()=" << traj.empty() << "EMPTY" << std::endl;
00151     if (theDbgFlg) cout << "TSB::addGroup : no groups left" << endl;
00152     if ( !traj.empty() )
00153       ret.push_back(traj);
00154     return ret;
00155   }
00156   
00157   if (theDbgFlg) cout << "TSB::addGroup : traj.size() = " << traj.measurements().size()
00158                       << " first group at " << &(*begin)
00159                    //        << " nr. of candidates = " << candidates.size() 
00160                       << endl;
00161 
00162 
00163   TempTrajectoryContainer updatedTrajectories; updatedTrajectories.reserve(2);
00164   if ( traj.measurements().empty() ) {
00165     vector<TM> firstMeasurements = unlockedMeasurements(begin->measurements());
00166     if ( theBestHitOnly )
00167       updateCandidatesWithBestHit(traj,firstMeasurements,updatedTrajectories);
00168     else
00169       updateCandidates(traj,begin->measurements(),updatedTrajectories);
00170     if (theDbgFlg) cout << "TSB::addGroup : updating with first group - "
00171                         << updatedTrajectories.size() << " trajectories" << endl;
00172   }
00173   else {
00174     if ( theBestHitOnly )
00175       updateCandidatesWithBestHit(traj,redoMeasurements(traj,begin->detGroup()),
00176                                   updatedTrajectories);
00177     else
00178       updateCandidates(traj,redoMeasurements(traj,begin->detGroup()),
00179                        updatedTrajectories);
00180     if (theDbgFlg) cout << "TSB::addGroup : updating"
00181                         << updatedTrajectories.size() << " trajectories" << endl;
00182   }
00183 
00184   if (begin+1 != end) {
00185       ret.reserve(4); // a good upper bound
00186       for ( TempTrajectoryContainer::iterator it=updatedTrajectories.begin();
00187             it!=updatedTrajectories.end(); ++it ) {
00188         if (theDbgFlg) cout << "TSB::addGroup : trying to extend candidate at "
00189                             << &(*it) << " size " << it->measurements().size() << endl;
00190         vector<TempTrajectory> finalTrajectories = addGroup(*it,begin+1,end);
00191         if (theDbgFlg) cout << "TSB::addGroup : " << finalTrajectories.size()
00192                             << " finalised candidates before cleaning" << endl;
00193         //B.M. to be ported later
00194         cleanCandidates(finalTrajectories);
00195 
00196         if (theDbgFlg) cout << "TSB::addGroup : got " << finalTrajectories.size()
00197                             << " finalised candidates" << endl;
00198         ret.insert(ret.end(),finalTrajectories.begin(),
00199                       finalTrajectories.end());
00200       }
00201   } else {
00202       ret.reserve(updatedTrajectories.size());
00203       for (TempTrajectoryContainer::iterator it=updatedTrajectories.begin(); 
00204               it!=updatedTrajectories.end(); ++it ) { 
00205         if (!it->empty()) ret.push_back(*it);
00206       }
00207   }
00208 
00209   //std::cout << "TrajectorySegmentBuilder::addGroup" << 
00210   //             " traj.empty()=" << traj.empty() << 
00211   //             " end-begin=" << (end-begin)  <<
00212   //             " #updated=" << updatedTrajectories.size() << 
00213   //             " #result=" << ret.size() << std::endl;
00214   return ret;
00215 }
00216 
00217 void
00218 TrajectorySegmentBuilder::updateCandidates (TempTrajectory& traj,
00219                                             const vector<TM>& measurements,
00220                                             TempTrajectoryContainer& candidates)
00221 {
00222   //
00223   // generate updated candidates with all valid hits
00224   //
00225   for ( vector<TM>::const_iterator im=measurements.begin();
00226         im!=measurements.end(); ++im ) {
00227     if ( im->recHit()->isValid() ) {
00228       candidates.push_back(traj);
00229       updateTrajectory(candidates.back(),*im);
00230       if ( theLockHits )  lockMeasurement(*im);
00231     }
00232   }
00233   //
00234   // keep old trajectory
00235   //
00236   candidates.push_back(traj);
00237 }
00238 
00239 void
00240 TrajectorySegmentBuilder::updateCandidatesWithBestHit (TempTrajectory& traj,
00241                                                        const vector<TM>& measurements,
00242                                                        TempTrajectoryContainer& candidates)
00243 {
00244   vector<TM>::const_iterator ibest = measurements.end();
00245   bool bestIsValid = false;
00246   for ( vector<TM>::const_iterator im=measurements.begin();
00247         im!=measurements.end(); ++im ) {
00248     if ( im->recHit()->isValid() ) {
00249         if (!bestIsValid || (ibest==measurements.end()) || (im->estimate()<ibest->estimate()) )  {
00250             ibest = im;
00251             bestIsValid = true;
00252         }
00253     } 
00254 //     else if (!bestIsValid && (im->recHit()->getType() != TrackingRecHit::missing)) {
00255 //         if (ibest==measurements.end()) ibest = im;
00256 //     }
00257   }
00258   if ( ibest!=measurements.end() ) {
00259     if ( theLockHits )  lockMeasurement(*ibest);
00260     candidates.push_back(traj);
00261     updateTrajectory(candidates.back(),*ibest);
00262     if ( theDbgFlg ) {
00263       if (bestIsValid) {
00264           cout << "TSB: found best measurement at " 
00265                << ibest->recHit()->globalPosition().perp() << " "
00266                << ibest->recHit()->globalPosition().phi() << " "
00267                << ibest->recHit()->globalPosition().z() << endl;
00268       } else {
00269         cout << "TSB: found best measurement at invalid hit on det " << ibest->recHit()->geographicalId().rawId() << endl;
00270       }
00271     }
00272   }
00273   //
00274   // keep old trajectorTempy
00275   //
00276   candidates.push_back(traj);
00277 }
00278 
00279 vector<TrajectoryMeasurement>
00280 TrajectorySegmentBuilder::redoMeasurements (const TempTrajectory& traj,
00281                                             const DetGroup& detGroup) const
00282 {
00283   vector<TM> result;
00284   vector<TM> tmpResult;
00285   //
00286   // loop over all dets
00287   //
00288   if (theDbgFlg) cout << "TSB::redoMeasurements : nr. of measurements / group =";
00289 
00290   for (DetGroup::const_iterator idet=detGroup.begin(); 
00291        idet!=detGroup.end(); ++idet) {
00292     //
00293     // ======== ask for measurements ==============       
00294     //B.M vector<TM> tmp = idet->det()->measurements(traj.lastMeasurement().updatedState(),
00295     //                                         theGeomPropagator,theEstimator);
00296     
00297     pair<bool, TrajectoryStateOnSurface> compat = 
00298       GeomDetCompatibilityChecker().isCompatible(idet->det(),
00299                                                  traj.lastMeasurement().updatedState(),
00300                                                  theGeomPropagator,theEstimator);
00301     
00302     vector<TM> tmp; 
00303     if(compat.first){
00304       const MeasurementDet* mdet = theMeasurementTracker->idToDet(idet->det()->geographicalId());
00305       tmp = mdet->fastMeasurements( compat.second, idet->trajectoryState(), theGeomPropagator, theEstimator);
00306     }
00307 
00308     //perhaps could be enough just:
00309     //vector<TM> tmp = mdet->fastMeasurements( idet->trajectoryState(),
00310     //                                       traj.lastMeasurement().updatedState(),
00311     //                                       theGeomPropagator, theEstimator);
00312     // ==================================================
00313 
00314     if ( tmp.empty() )  continue;
00315     //
00316     // only collect valid RecHits
00317     //
00318     vector<TM>::iterator end = (tmp.back().recHit()->getType() != TrackingRecHit::missing ? tmp.end() : tmp.end()-1);
00319     if (theDbgFlg) cout << " " << tmp.size();
00320     tmpResult.insert(tmpResult.end(),tmp.begin(),end);
00321   }
00322   if (theDbgFlg) cout << endl;
00323   //
00324   // set layer in TM, because the Det cannot do it
00325   //
00326   for(vector<TM>::const_iterator tmpIt=tmpResult.begin();tmpIt!=tmpResult.end();++tmpIt){
00327     if ( tmpIt->recHit()->isValid() )
00328       result.push_back(  TrajectoryMeasurement(tmpIt->predictedState(),tmpIt->recHit(),tmpIt->estimate(),&theLayer)  );
00329   }
00330   
00331   return result;
00332 }
00333 
00334 void 
00335 TrajectorySegmentBuilder::updateWithInvalidHit (TempTrajectory& traj,
00336                                                 const vector<TMG>& groups,
00337                                                 TempTrajectoryContainer& candidates) const
00338 {
00339   //
00340   // first try to find an inactive hit with dets crossed by the prediction,
00341   //   then take any inactive hit
00342   //
00343   // loop over groups
00344   for ( int iteration=0; iteration<2; iteration++ ) {
00345     for ( vector<TMG>::const_iterator ig=groups.begin(); ig!=groups.end(); ++ig) {
00346       // loop over measurements
00347       const vector<TM>& measurements = ig->measurements();
00348       for ( vector<TM>::const_reverse_iterator im=measurements.rbegin();
00349             im!=measurements.rend(); ++im ) {
00350         ConstRecHitPointer hit = im->recHit();
00351         if ( hit->getType()==TrackingRecHit::valid ||
00352              hit->getType()==TrackingRecHit::missing )  continue;
00353         //
00354         // check, if the extrapolation traverses the Det or
00355         // if 2nd iteration
00356         //
00357         if ( hit->det() ) {
00358           TSOS predState(im->predictedState());
00359           if ( iteration>0 || 
00360                (predState.isValid() &&
00361                 hit->det()->surface().bounds().inside(predState.localPosition())) ) {
00362             // add the hit
00363             /*TempTrajectory newTraj(traj);
00364             updateTrajectory(newTraj,*im);
00365             candidates.push_back(newTraj);  // FIXME: avoid useless copy */
00366             candidates.push_back(traj); 
00367             updateTrajectory(candidates.back(), *im);
00368             if ( theDbgFlg ) cout << "TrajectorySegmentBuilder::updateWithInvalidHit "
00369                                   << "added inactive hit" << endl;
00370             return;
00371           }
00372         }
00373       }
00374     }
00375   }
00376   //
00377   // No suitable inactive hit: add a missing one
00378   //
00379   bool found(false);
00380   for ( int iteration=0; iteration<2; iteration++ ) {
00381     //
00382     // loop over groups
00383     //
00384     for ( vector<TMG>::const_iterator ig=groups.begin();
00385           ig!=groups.end(); ++ig) {
00386       const vector<TM>& measurements = ig->measurements();
00387       for ( vector<TM>::const_reverse_iterator im=measurements.rbegin();
00388             im!=measurements.rend(); ++im ) {
00389         //
00390         // only use invalid hits
00391         //
00392         ConstRecHitPointer hit = im->recHit();
00393         if ( hit->isValid() )  continue;
00394 
00395         //
00396         // check, if the extrapolation traverses the Det
00397         //
00398         TSOS predState(im->predictedState());
00399         if(hit->det()){ 
00400           if ( iteration>0 || (predState.isValid() &&
00401                                hit->det()->surface().bounds().inside(predState.localPosition())) ) {
00402             // add invalid hit
00403             /*TempTrajectory newTraj(traj);
00404             updateTrajectory(newTraj,*im);
00405             candidates.push_back(newTraj);  // FIXME: avoid useless copy */
00406             candidates.push_back(traj); 
00407             updateTrajectory(candidates.back(), *im);
00408             found = true;
00409             break;
00410           }
00411 
00412         }else{
00413           if ( iteration>0 || (predState.isValid() &&
00414                                im->layer()->surface().bounds().inside(predState.localPosition())) ){
00415             // add invalid hit
00416             /*TempTrajectory newTraj(traj);
00417             updateTrajectory(newTraj,*im);
00418             candidates.push_back(newTraj);  // FIXME: avoid useless copy */
00419             candidates.push_back(traj); 
00420             updateTrajectory(candidates.back(), *im);
00421             found = true;
00422             break;          
00423           }
00424         }
00425       }
00426       if ( found )  break;
00427     }
00428     if ( theDbgFlg && !found ) cout << "TrajectorySegmentBuilder::updateWithInvalidHit: "
00429                                     << " did not find invalid hit on 1st iteration" << endl;
00430     if ( found )  break;
00431   }
00432   if ( !found ) {
00433     if (theDbgFlg) cout << "TrajectorySegmentBuilder::updateWithInvalidHit: "
00434                         << " did not find invalid hit" << endl;
00435   }
00436 }
00437 
00438 vector<TrajectoryMeasurement>
00439 TrajectorySegmentBuilder::unlockedMeasurements (const vector<TM>& measurements) const
00440 {
00441 //   if ( !theLockHits )  return measurements;
00442 
00443   //========== B.M. to be ported later ===============
00444   vector<TM> result;
00445   result.reserve(measurements.size());
00446 
00447   //RecHitEqualByChannels recHitEqual(false,true);
00448 
00449   for ( vector<TM>::const_iterator im=measurements.begin();
00450         im!=measurements.end(); ++im ) {
00451     ConstRecHitPointer testHit = im->recHit();
00452     if ( !testHit->isValid() )  continue;
00453     bool found(false);
00454     if ( theLockHits ) {
00455       for ( ConstRecHitContainer::const_iterator ih=theLockedHits.begin();
00456             ih!=theLockedHits.end(); ++ih ) {
00457         if ( (*ih)->hit()->sharesInput(testHit->hit(), TrackingRecHit::all) ) {
00458           found = true;
00459           break;
00460         }
00461       }
00462     }
00463     if ( !found )  result.push_back(*im);
00464   }
00465   return result;
00466   //================================= 
00467   //return measurements; // temporary solution before RecHitEqualByChannels is ported
00468 }
00469 
00470 void
00471 TrajectorySegmentBuilder::lockMeasurement (const TM& measurement)
00472 {
00473   theLockedHits.push_back(measurement.recHit());
00474 }
00475 
00476 
00477 
00478 // ================= B.M. to be ported later ===============================
00479 void
00480 TrajectorySegmentBuilder::cleanCandidates (vector<TempTrajectory>& candidates) const
00481 {
00482   //
00483   // remove candidates which are subsets of others
00484   // assumptions: no invalid hits and no duplicates
00485   //
00486   if ( candidates.size()<=1 )  return;
00487   //RecHitEqualByChannels recHitEqual(false,true);
00488   //
00489   vector<TempTrajectory> sortedCandidates(candidates);
00490   sort(sortedCandidates.begin(),sortedCandidates.end(),TrajectoryLessByFoundHits());
00491 //   cout << "SortedCandidates.foundHits";
00492 //   for ( vector<Trajectory>::iterator i1=sortedCandidates.begin();
00493 //      i1!=sortedCandidates.end(); i1++ ) 
00494 //     cout << " " << i1->foundHits();
00495 //   cout << endl;
00496   //
00497   for ( vector<TempTrajectory>::iterator i1=sortedCandidates.begin();
00498         i1!=sortedCandidates.end()-1; ++i1 ) {
00499     // get measurements of candidate to be checked
00500     const TempTrajectory::DataContainer & measurements1 = i1->measurements();
00501     for ( vector<TempTrajectory>::iterator i2=i1+1;
00502           i2!=sortedCandidates.end(); ++i2 ) {
00503       // no duplicates: two candidates of same size are different
00504       if ( i2->foundHits()==i1->foundHits() )  continue;
00505       // get measurements of "reference"
00506       const TempTrajectory::DataContainer & measurements2 = i2->measurements();
00507       //
00508       // use the fact that TMs are ordered:
00509       // start search in trajectory#1 from last hit match found
00510       //
00511       bool allFound(true);
00512       TempTrajectory::DataContainer::const_iterator from2 = measurements2.rbegin(), im2end = measurements2.rend();
00513       for ( TempTrajectory::DataContainer::const_iterator im1=measurements1.rbegin(),im1end = measurements1.rend();
00514             im1!=im1end; --im1 ) {
00515         // redundant protection - segments should not contain invalid RecHits
00516         if ( !im1->recHit()->isValid() )  continue;
00517         bool found(false);
00518         for ( TempTrajectory::DataContainer::const_iterator im2=from2;
00519               im2!=im2end; --im2 ) {
00520           // redundant protection - segments should not contain invalid RecHits
00521           if ( !im2->recHit()->isValid() )  continue;
00522           if ( im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::all) ) {
00523             found = true;
00524             from2 = im2; --from2;
00525             break;
00526           }
00527         }
00528         if ( !found ) {
00529           allFound = false;
00530           break;
00531         }
00532       }
00533       if ( allFound )  i1->invalidate();
00534     }
00535   }
00536 /*
00537   candidates.clear();
00538   for ( vector<Trajectory>::const_iterator i=sortedCandidates.begin();
00539         i!=sortedCandidates.end(); i++ ) {
00540     if ( i->isValid() )  candidates.push_back(*i);
00541   }
00542 */
00543   candidates.erase(std::remove_if( candidates.begin(),candidates.end(),
00544                                    std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
00545  //                                boost::bind(&TempTrajectory::isValid,_1)), 
00546                                    candidates.end()); 
00547 #ifdef DBG_TSB
00548   cout << "TSB: cleanCandidates: reduced from " << sortedCandidates.size()
00549        << " to " << candidates.size() << " candidates" << endl;
00550 #endif
00551   return;
00552 }
00553 
00554 //==================================================

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