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