00001
00002 #include "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 namespace {
00025 #ifdef STAT_TSB
00026 struct StatCount {
00027 long long totGroup;
00028 long long totSeg;
00029 long long totLockHits;
00030 void zero() {
00031 totGroup=totSeg=totLockHits=0;
00032 }
00033 void incr(long long g, long long s, long long l) {
00034 totGroup+=g;
00035 totSeg+=s;
00036 totLockHits+=l;
00037 }
00038 void print() const {
00039 std::cout << "TrajectorySegmentBuilder stat\nGroup/Seg/Lock "
00040 << totGroup<<'/'<<totSeg<<'/'<<totLockHits
00041 << std::endl;
00042 }
00043 StatCount() { zero();}
00044 ~StatCount() { print();}
00045 };
00046
00047 #else
00048 struct StatCount {
00049 void incr(long long, long long, long long){}
00050 };
00051 #endif
00052
00053 StatCount statCount;
00054
00055 }
00056
00057
00058 using namespace std;
00059
00060 TrajectorySegmentBuilder::TempTrajectoryContainer
00061 TrajectorySegmentBuilder::segments (const TSOS startingState)
00062 {
00063
00064
00065
00066 theLockedHits.clear();
00067 TempTrajectory startingTrajectory(theFullPropagator.propagationDirection());
00068
00069
00070
00071 vector<TMG> measGroups =
00072 theLayerMeasurements->groupedMeasurements(theLayer,startingState,theFullPropagator,theEstimator);
00073
00074
00075 #ifdef DBG_TSB
00076 cout << "TSB: number of measurement groups = " << measGroups.size() << endl;
00077
00078 theDbgFlg = true;
00079 #else
00080 theDbgFlg = false;
00081 #endif
00082
00083
00084 #ifdef DBG_TSB
00085 if ( theDbgFlg ) {
00086 int ntot(1);
00087 for (vector<TMG>::const_iterator ig=measGroups.begin();
00088 ig!=measGroups.end(); ++ig) {
00089 int ngrp(0);
00090 const vector<TM>& measurements = ig->measurements();
00091 for ( vector<TM>::const_iterator im=measurements.begin();
00092 im!=measurements.end(); ++im ) {
00093 if ( im->recHit()->isValid() ) ngrp++;
00094 }
00095 cout << " " << ngrp;
00096 if ( ngrp>0 ) ntot *= ngrp;
00097 }
00098 cout << endl;
00099 cout << "TrajectorySegmentBuilder::partialTrajectories:: det ids & hit types / group" << endl;
00100 for (vector<TMG>::const_iterator ig=measGroups.begin();
00101 ig!=measGroups.end(); ++ig) {
00102 const vector<TM>& measurements = ig->measurements();
00103 for ( vector<TM>::const_iterator im=measurements.begin();
00104 im!=measurements.end(); ++im ) {
00105 if ( im!=measurements.begin() ) cout << " / ";
00106 if ( im->recHit()->det() )
00107 cout << im->recHit()->det()->geographicalId().rawId() << " "
00108 << im->recHit()->getType();
00109 else
00110 cout << "no det";
00111 }
00112 cout << endl;
00113 }
00114
00115
00116
00117 cout << typeid(theLayer).name() << endl;
00118 cout << startingState.localError().matrix() << endl;
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 }
00133 #endif
00134
00135 TempTrajectoryContainer candidates =
00136 addGroup(startingTrajectory,measGroups.begin(),measGroups.end());
00137
00138 if (theDbgFlg) cout << "TSB: back with " << candidates.size() << " candidates" << endl;
00139
00140
00141
00142
00143
00144
00145 updateWithInvalidHit(startingTrajectory,measGroups,candidates);
00146
00147 if (theDbgFlg) cout << "TSB: " << candidates.size() << " candidates after invalid hit" << endl;
00148
00149 statCount.incr(measGroups.size(), candidates.size(), theLockedHits.size());
00150
00151
00152 theLockedHits.clear();
00153
00154 return candidates;
00155 }
00156
00157 void TrajectorySegmentBuilder::updateTrajectory (TempTrajectory& traj,
00158 const TM& tm) const
00159 {
00160 TSOS predictedState = tm.predictedState();
00161 ConstRecHitPointer hit = tm.recHit();
00162
00163 if ( hit->isValid()) {
00164 traj.push( TM( predictedState, theUpdator.update( predictedState, *hit),
00165 hit, tm.estimate(), tm.layer()));
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 }
00180 else {
00181 traj.push( TM( predictedState, hit,0, tm.layer()));
00182 }
00183 }
00184
00185
00186 TrajectorySegmentBuilder::TempTrajectoryContainer
00187 TrajectorySegmentBuilder::addGroup (TempTrajectory& traj,
00188 vector<TMG>::const_iterator begin,
00189 vector<TMG>::const_iterator end)
00190 {
00191 vector<TempTrajectory> ret;
00192 if ( begin==end ) {
00193
00194 if (theDbgFlg) cout << "TSB::addGroup : no groups left" << endl;
00195 if ( !traj.empty() )
00196 ret.push_back(traj);
00197 return ret;
00198 }
00199
00200 if (theDbgFlg) cout << "TSB::addGroup : traj.size() = " << traj.measurements().size()
00201 << " first group at " << &(*begin)
00202
00203 << endl;
00204
00205
00206 TempTrajectoryContainer updatedTrajectories; updatedTrajectories.reserve(2);
00207 if ( traj.measurements().empty() ) {
00208 vector<TM> firstMeasurements = unlockedMeasurements(begin->measurements());
00209 if ( theBestHitOnly )
00210 updateCandidatesWithBestHit(traj,firstMeasurements,updatedTrajectories);
00211 else
00212 updateCandidates(traj,begin->measurements(),updatedTrajectories);
00213 if (theDbgFlg) cout << "TSB::addGroup : updating with first group - "
00214 << updatedTrajectories.size() << " trajectories" << endl;
00215 }
00216 else {
00217 if ( theBestHitOnly )
00218 updateCandidatesWithBestHit(traj,redoMeasurements(traj,begin->detGroup()),
00219 updatedTrajectories);
00220 else
00221 updateCandidates(traj,redoMeasurements(traj,begin->detGroup()),
00222 updatedTrajectories);
00223 if (theDbgFlg) cout << "TSB::addGroup : updating"
00224 << updatedTrajectories.size() << " trajectories" << endl;
00225 }
00226
00227 if (begin+1 != end) {
00228 ret.reserve(4);
00229 for ( TempTrajectoryContainer::iterator it=updatedTrajectories.begin();
00230 it!=updatedTrajectories.end(); ++it ) {
00231 if (theDbgFlg) cout << "TSB::addGroup : trying to extend candidate at "
00232 << &(*it) << " size " << it->measurements().size() << endl;
00233 vector<TempTrajectory> finalTrajectories = addGroup(*it,begin+1,end);
00234 if (theDbgFlg) cout << "TSB::addGroup : " << finalTrajectories.size()
00235 << " finalised candidates before cleaning" << endl;
00236
00237 cleanCandidates(finalTrajectories);
00238
00239 if (theDbgFlg) cout << "TSB::addGroup : got " << finalTrajectories.size()
00240 << " finalised candidates" << endl;
00241 ret.insert(ret.end(),finalTrajectories.begin(),
00242 finalTrajectories.end());
00243 }
00244 } else {
00245 ret.reserve(updatedTrajectories.size());
00246 for (TempTrajectoryContainer::iterator it=updatedTrajectories.begin();
00247 it!=updatedTrajectories.end(); ++it ) {
00248 if (!it->empty()) ret.push_back(*it);
00249 }
00250 }
00251
00252
00253
00254
00255
00256
00257 return ret;
00258 }
00259
00260 void
00261 TrajectorySegmentBuilder::updateCandidates (TempTrajectory& traj,
00262 const vector<TM>& measurements,
00263 TempTrajectoryContainer& candidates)
00264 {
00265
00266
00267
00268 for ( vector<TM>::const_iterator im=measurements.begin();
00269 im!=measurements.end(); ++im ) {
00270 if ( im->recHit()->isValid() ) {
00271 candidates.push_back(traj);
00272 updateTrajectory(candidates.back(),*im);
00273 if ( theLockHits ) lockMeasurement(*im);
00274 }
00275 }
00276
00277
00278
00279 candidates.push_back(traj);
00280 }
00281
00282 void
00283 TrajectorySegmentBuilder::updateCandidatesWithBestHit (TempTrajectory& traj,
00284 const vector<TM>& measurements,
00285 TempTrajectoryContainer& candidates)
00286 {
00287 vector<TM>::const_iterator ibest = measurements.begin();
00288
00289 while(ibest!=measurements.end() && !ibest->recHit()->isValid()) ++ibest;
00290 if ( ibest!=measurements.end() ) {
00291
00292 for ( vector<TM>::const_iterator im=ibest+1;
00293 im!=measurements.end(); ++im ) {
00294 if ( im->recHit()->isValid() &&
00295 im->estimate()<ibest->estimate()
00296 )
00297 ibest = im;
00298 }
00299
00300
00301 if ( theLockHits ) lockMeasurement(*ibest);
00302 candidates.push_back(traj);
00303 updateTrajectory(candidates.back(),*ibest);
00304
00305 if ( theDbgFlg )
00306 cout << "TSB: found best measurement at "
00307 << ibest->recHit()->globalPosition().perp() << " "
00308 << ibest->recHit()->globalPosition().phi() << " "
00309 << ibest->recHit()->globalPosition().z() << endl;
00310
00311 }
00312
00313
00314
00315
00316 candidates.push_back(traj);
00317 }
00318
00319 vector<TrajectoryMeasurement>
00320 TrajectorySegmentBuilder::redoMeasurements (const TempTrajectory& traj,
00321 const DetGroup& detGroup) const
00322 {
00323 vector<TM> result;
00324
00325
00326
00327 if (theDbgFlg) cout << "TSB::redoMeasurements : nr. of measurements / group =";
00328
00329 for (DetGroup::const_iterator idet=detGroup.begin();
00330 idet!=detGroup.end(); ++idet) {
00331
00332
00333
00334
00335
00336 pair<bool, TrajectoryStateOnSurface> compat =
00337 GeomDetCompatibilityChecker().isCompatible(idet->det(),
00338 traj.lastMeasurement().updatedState(),
00339 theGeomPropagator,theEstimator);
00340
00341 if (theDbgFlg && !compat.first) cout << " 0";
00342
00343 if(!compat.first) continue;
00344 const MeasurementDet* mdet = theMeasurementTracker->idToDet(idet->det()->geographicalId());
00345 vector<TM> tmp
00346 = mdet->fastMeasurements( compat.second, idet->trajectoryState(), theGeomPropagator, theEstimator);
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 if (theDbgFlg) cout << " " << tmp.size();
00359
00360 for(vector<TM>::iterator tmpIt=tmp.begin(); tmpIt!=tmp.end(); ++tmpIt){
00361 if ( tmpIt->recHit()->isValid() ) {
00362 tmpIt->setLayer(&theLayer);
00363 result.push_back(*tmpIt);
00364 }
00365 }
00366 }
00367 if (theDbgFlg) cout << endl;
00368
00369 return result;
00370 }
00371
00372 void
00373 TrajectorySegmentBuilder::updateWithInvalidHit (TempTrajectory& traj,
00374 const vector<TMG>& groups,
00375 TempTrajectoryContainer& candidates) const
00376 {
00377
00378
00379
00380
00381
00382 for ( int iteration=0; iteration<2; iteration++ ) {
00383 for ( vector<TMG>::const_iterator ig=groups.begin(); ig!=groups.end(); ++ig) {
00384
00385 const vector<TM>& measurements = ig->measurements();
00386 for ( vector<TM>::const_reverse_iterator im=measurements.rbegin();
00387 im!=measurements.rend(); ++im ) {
00388 ConstRecHitPointer hit = im->recHit();
00389 if ( hit->getType()==TrackingRecHit::valid ||
00390 hit->getType()==TrackingRecHit::missing ) continue;
00391
00392
00393
00394
00395 if ( hit->det() ) {
00396 TSOS predState(im->predictedState());
00397 if ( iteration>0 ||
00398 (predState.isValid() &&
00399 hit->det()->surface().bounds().inside(predState.localPosition())) ) {
00400
00401
00402
00403
00404 candidates.push_back(traj);
00405 updateTrajectory(candidates.back(), *im);
00406 if ( theDbgFlg ) cout << "TrajectorySegmentBuilder::updateWithInvalidHit "
00407 << "added inactive hit" << endl;
00408 return;
00409 }
00410 }
00411 }
00412 }
00413 }
00414
00415
00416
00417 bool found(false);
00418 for ( int iteration=0; iteration<2; iteration++ ) {
00419
00420
00421
00422 for ( vector<TMG>::const_iterator ig=groups.begin();
00423 ig!=groups.end(); ++ig) {
00424 const vector<TM>& measurements = ig->measurements();
00425 for ( vector<TM>::const_reverse_iterator im=measurements.rbegin();
00426 im!=measurements.rend(); ++im ) {
00427
00428
00429
00430 ConstRecHitPointer hit = im->recHit();
00431 if ( hit->isValid() ) continue;
00432
00433
00434
00435
00436 TSOS predState(im->predictedState());
00437 if(hit->det()){
00438 if ( iteration>0 || (predState.isValid() &&
00439 hit->det()->surface().bounds().inside(predState.localPosition())) ) {
00440
00441
00442
00443
00444 candidates.push_back(traj);
00445 updateTrajectory(candidates.back(), *im);
00446 found = true;
00447 break;
00448 }
00449
00450 }else{
00451 if ( iteration>0 || (predState.isValid() &&
00452 im->layer()->surface().bounds().inside(predState.localPosition())) ){
00453
00454
00455
00456
00457 candidates.push_back(traj);
00458 updateTrajectory(candidates.back(), *im);
00459 found = true;
00460 break;
00461 }
00462 }
00463 }
00464 if ( found ) break;
00465 }
00466 if ( theDbgFlg && !found ) cout << "TrajectorySegmentBuilder::updateWithInvalidHit: "
00467 << " did not find invalid hit on 1st iteration" << endl;
00468 if ( found ) break;
00469 }
00470 if ( !found ) {
00471 if (theDbgFlg) cout << "TrajectorySegmentBuilder::updateWithInvalidHit: "
00472 << " did not find invalid hit" << endl;
00473 }
00474 }
00475
00476 vector<TrajectoryMeasurement>
00477 TrajectorySegmentBuilder::unlockedMeasurements (const vector<TM>& measurements) const
00478 {
00479
00480
00481
00482 vector<TM> result;
00483 result.reserve(measurements.size());
00484
00485
00486
00487 for ( vector<TM>::const_iterator im=measurements.begin();
00488 im!=measurements.end(); ++im ) {
00489 ConstRecHitPointer testHit = im->recHit();
00490 if ( !testHit->isValid() ) continue;
00491 bool found(false);
00492 if ( theLockHits ) {
00493 for ( ConstRecHitContainer::const_iterator ih=theLockedHits.begin();
00494 ih!=theLockedHits.end(); ++ih ) {
00495 if ( (*ih)->hit()->sharesInput(testHit->hit(), TrackingRecHit::all) ) {
00496 found = true;
00497 break;
00498 }
00499 }
00500 }
00501 if ( !found ) result.push_back(*im);
00502 }
00503 return result;
00504
00505
00506 }
00507
00508 void
00509 TrajectorySegmentBuilder::lockMeasurement (const TM& measurement)
00510 {
00511 theLockedHits.push_back(measurement.recHit());
00512 }
00513
00514
00515
00516
00517 void
00518 TrajectorySegmentBuilder::cleanCandidates (vector<TempTrajectory>& candidates) const
00519 {
00520
00521
00522
00523
00524 if ( candidates.size()<=1 ) return;
00525
00526
00527 vector<TempTrajectory> sortedCandidates(candidates);
00528 sort(sortedCandidates.begin(),sortedCandidates.end(),TrajectoryLessByFoundHits());
00529
00530
00531
00532
00533
00534
00535 for ( vector<TempTrajectory>::iterator i1=sortedCandidates.begin();
00536 i1!=sortedCandidates.end()-1; ++i1 ) {
00537
00538 const TempTrajectory::DataContainer & measurements1 = i1->measurements();
00539 for ( vector<TempTrajectory>::iterator i2=i1+1;
00540 i2!=sortedCandidates.end(); ++i2 ) {
00541
00542 if ( i2->foundHits()==i1->foundHits() ) continue;
00543
00544 const TempTrajectory::DataContainer & measurements2 = i2->measurements();
00545
00546
00547
00548
00549 bool allFound(true);
00550 TempTrajectory::DataContainer::const_iterator from2 = measurements2.rbegin(), im2end = measurements2.rend();
00551 for ( TempTrajectory::DataContainer::const_iterator im1=measurements1.rbegin(),im1end = measurements1.rend();
00552 im1!=im1end; --im1 ) {
00553
00554 if ( !im1->recHit()->isValid() ) continue;
00555 bool found(false);
00556 for ( TempTrajectory::DataContainer::const_iterator im2=from2;
00557 im2!=im2end; --im2 ) {
00558
00559 if ( !im2->recHit()->isValid() ) continue;
00560 if ( im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::all) ) {
00561 found = true;
00562 from2 = im2; --from2;
00563 break;
00564 }
00565 }
00566 if ( !found ) {
00567 allFound = false;
00568 break;
00569 }
00570 }
00571 if ( allFound ) i1->invalidate();
00572 }
00573 }
00574
00575
00576
00577
00578
00579
00580
00581 candidates.erase(std::remove_if( candidates.begin(),candidates.end(),
00582 std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
00583
00584 candidates.end());
00585 #ifdef DBG_TSB
00586 cout << "TSB: cleanCandidates: reduced from " << sortedCandidates.size()
00587 << " to " << candidates.size() << " candidates" << endl;
00588 #endif
00589 return;
00590 }
00591
00592