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
00023
00024 using namespace std;
00025
00026 TrajectorySegmentBuilder::TempTrajectoryContainer
00027 TrajectorySegmentBuilder::segments (const TSOS startingState)
00028 {
00029
00030
00031
00032 theLockedHits.clear();
00033 TrajectorySeed invalidSeed;
00034 TempTrajectory startingTrajectory(invalidSeed,theFullPropagator.propagationDirection());
00035
00036
00037
00038 vector<TMG> measGroups =
00039 theLayerMeasurements->groupedMeasurements(theLayer,startingState,theFullPropagator,theEstimator);
00040
00041
00042 #ifdef DBG_TSB
00043 cout << "TSB: number of measurement groups = " << measGroups.size() << endl;
00044
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
00083 cout << typeid(theLayer).name() << endl;
00084 cout << startingState.localError().matrix() << endl;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
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
00105
00106
00107
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
00125
00126
00127
00128
00129
00130
00131
00132
00133
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
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
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);
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
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
00210
00211
00212
00213
00214 return ret;
00215 }
00216
00217 void
00218 TrajectorySegmentBuilder::updateCandidates (TempTrajectory& traj,
00219 const vector<TM>& measurements,
00220 TempTrajectoryContainer& candidates)
00221 {
00222
00223
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
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
00255
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
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
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
00294
00295
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
00309
00310
00311
00312
00313
00314 if ( tmp.empty() ) continue;
00315
00316
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
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
00341
00342
00343
00344 for ( int iteration=0; iteration<2; iteration++ ) {
00345 for ( vector<TMG>::const_iterator ig=groups.begin(); ig!=groups.end(); ++ig) {
00346
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
00355
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
00363
00364
00365
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
00378
00379 bool found(false);
00380 for ( int iteration=0; iteration<2; iteration++ ) {
00381
00382
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
00391
00392 ConstRecHitPointer hit = im->recHit();
00393 if ( hit->isValid() ) continue;
00394
00395
00396
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
00403
00404
00405
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
00416
00417
00418
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
00442
00443
00444 vector<TM> result;
00445 result.reserve(measurements.size());
00446
00447
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
00468 }
00469
00470 void
00471 TrajectorySegmentBuilder::lockMeasurement (const TM& measurement)
00472 {
00473 theLockedHits.push_back(measurement.recHit());
00474 }
00475
00476
00477
00478
00479 void
00480 TrajectorySegmentBuilder::cleanCandidates (vector<TempTrajectory>& candidates) const
00481 {
00482
00483
00484
00485
00486 if ( candidates.size()<=1 ) return;
00487
00488
00489 vector<TempTrajectory> sortedCandidates(candidates);
00490 sort(sortedCandidates.begin(),sortedCandidates.end(),TrajectoryLessByFoundHits());
00491
00492
00493
00494
00495
00496
00497 for ( vector<TempTrajectory>::iterator i1=sortedCandidates.begin();
00498 i1!=sortedCandidates.end()-1; ++i1 ) {
00499
00500 const TempTrajectory::DataContainer & measurements1 = i1->measurements();
00501 for ( vector<TempTrajectory>::iterator i2=i1+1;
00502 i2!=sortedCandidates.end(); ++i2 ) {
00503
00504 if ( i2->foundHits()==i1->foundHits() ) continue;
00505
00506 const TempTrajectory::DataContainer & measurements2 = i2->measurements();
00507
00508
00509
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
00516 if ( !im1->recHit()->isValid() ) continue;
00517 bool found(false);
00518 for ( TempTrajectory::DataContainer::const_iterator im2=from2;
00519 im2!=im2end; --im2 ) {
00520
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
00538
00539
00540
00541
00542
00543 candidates.erase(std::remove_if( candidates.begin(),candidates.end(),
00544 std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
00545
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