CMS 3D CMS Logo

GroupedCkfTrajectoryBuilder.cc
Go to the documentation of this file.
3 
4 
7 
11 #include "GroupedTrajCandLess.h"
23 
31 
33 
34 
35 // only included for RecHit comparison operator:
37 
39 
40 
41 // for looper reconstruction
45 
47 
48 #include <algorithm>
49 #include <array>
50 
51 // #define STAT_TSB
52 
53 namespace {
54 #ifdef STAT_TSB
55  struct StatCount {
56  long long totSeed;
57  long long totTraj;
58  long long totRebuilt;
59  long long totInvCand;
60  void zero() {
61  totSeed=totTraj=totRebuilt=totInvCand=0;
62  }
63  void traj(long long t) {
64  totTraj+=t;
65  }
66  void seed() {++totSeed;}
67  void rebuilt(long long t) {
68  totRebuilt+=t;
69  }
70  void invalid() { ++totInvCand;}
71  void print() const {
72  std::cout << "GroupedCkfTrajectoryBuilder stat\nSeed/Traj/Rebuilt "
73  << totSeed <<'/'<< totTraj <<'/'<< totRebuilt
74  << std::endl;
75  }
76  StatCount() { zero();}
77  ~StatCount() { print();}
78  };
79  StatCount statCount;
80 
81 #else
82  struct StatCount {
83  void traj(long long){}
84  void seed() {}
85  void rebuilt(long long) {}
86  void invalid() {}
87  };
88  [[cms::thread_safe]] StatCount statCount;
89 #endif
90 
91 
92 }
93 
94 
95 
96 using namespace std;
97 
98 //#define DBG2_GCTB
99 
100 //#define STANDARD_INTERMEDIARYCLEAN
101 
102 #ifdef STANDARD_INTERMEDIARYCLEAN
104 #endif
105 
106 /* ====== B.M. to be ported layer ===========
107 #ifdef DBG_GCTB
108 #include "RecoTracker/CkfPattern/src/ShowCand.h"
109 #endif
110 // #define DBG2_GCTB
111 #ifdef DBG2_GCTB
112 #include "RecoTracker/CkfPattern/src/SimIdPrinter.h"
113 #include "Tracker/TkDebugTools/interface/LayerFinderByDet.h"
114 #include "Tracker/TkLayout/interface/TkLayerName.h"
115 #endif
116 =================================== */
117 
118 
119 namespace {
120 
122 
123 }
124 
125 
128  BaseCkfTrajectoryBuilder::createTrajectoryFilter(conf.getParameter<edm::ParameterSet>("trajectoryFilter"), iC),
129  conf.getParameter<bool>("useSameTrajFilter") ?
130  BaseCkfTrajectoryBuilder::createTrajectoryFilter(conf.getParameter<edm::ParameterSet>("trajectoryFilter"), iC) :
131  BaseCkfTrajectoryBuilder::createTrajectoryFilter(conf.getParameter<edm::ParameterSet>("inOutTrajectoryFilter"), iC)
132  )
133 {
134  // fill data members from parameters (eventually data members could be dropped)
135  //
136  theMaxCand = conf.getParameter<int>("maxCand");
137  theLostHitPenalty = conf.getParameter<double>("lostHitPenalty");
138  theFoundHitBonus = conf.getParameter<double>("foundHitBonus");
139  theIntermediateCleaning = conf.getParameter<bool>("intermediateCleaning");
140  theAlwaysUseInvalid = conf.getParameter<bool>("alwaysUseInvalidHits");
141  theLockHits = conf.getParameter<bool>("lockHits");
142  theBestHitOnly = conf.getParameter<bool>("bestHitOnly");
144  theRequireSeedHitsInRebuild = conf.getParameter<bool>("requireSeedHitsInRebuild");
145  theKeepOriginalIfRebuildFails = conf.getParameter<bool>("keepOriginalIfRebuildFails");
146  theMinNrOfHitsForRebuild = max(0,conf.getParameter<int>("minNrOfHitsForRebuild"));
147  maxPt2ForLooperReconstruction = conf.existsAs<double>("maxPtForLooperReconstruction") ?
148  conf.getParameter<double>("maxPtForLooperReconstruction") : 0;
150  maxDPhiForLooperReconstruction = conf.existsAs<double>("maxDPhiForLooperReconstruction") ?
151  conf.getParameter<double>("maxDPhiForLooperReconstruction") : 2.0;
152 
153 
154  /* ======= B.M. to be ported layer ===========
155  bool setOK = thePropagator->setMaxDirectionChange(1.6);
156  if (!setOK)
157  cout << "GroupedCkfTrajectoryBuilder WARNING: "
158  << "propagator does not support setMaxDirectionChange"
159  << endl;
160  // addStopCondition(theMinPtStopCondition);
161 
162  theConfigurableCondition = createAlgo<TrajectoryFilter>(componentConfig("StopCondition"));
163  ===================================== */
164 
165 }
166 
167 /*
168  void GroupedCkfTrajectoryBuilder::setEvent(const edm::Event& event) const
169  {
170  theMeasurementTracker->update(event);
171 }
172 */
173 
175 }
176 
179 {
180  TrajectoryContainer ret;
181  ret.reserve(10);
182  buildTrajectories(seed, ret, 0);
183  return ret;
184 }
185 
188  const TrackingRegion& region) const
189 {
190  TrajectoryContainer ret;
191  ret.reserve(10);
192  RegionalTrajectoryFilter regionalCondition(region);
193  buildTrajectories(seed, ret, &regionalCondition);
194  return ret;
195 }
196 
197 void
199 {
200  buildTrajectories(seed,ret,0);
201 }
202 
203 void
206  const TrackingRegion& region) const
207 {
208  RegionalTrajectoryFilter regionalCondition(region);
209  buildTrajectories(seed,ret,&regionalCondition);
210 }
211 
212 void
214  TrajectoryContainer& result) const {
215  TempTrajectory const & startingTraj = createStartingTrajectory( seed);
216  rebuildTrajectories(startingTraj,seed,result);
217 
218 }
219 
220 void
222  TrajectoryContainer& result) const {
224 
225  TrajectoryContainer final;
226 
227  // better the seed to be always the same...
228  boost::shared_ptr<const TrajectorySeed> sharedSeed;
229  if (result.empty())
230  sharedSeed.reset(new TrajectorySeed(seed));
231  else sharedSeed = result.front().sharedSeed();
232 
233 
234  work.reserve(result.size());
235  for (auto && traj : result)
236  if(traj.isValid()) work.emplace_back(std::move(traj));
237 
238 
239  rebuildSeedingRegion(seed,startingTraj,work);
240 
241  // we clean here now
243  cleaner.clean(work);
244 
245  for (auto const & it : work) if (it.isValid()) {
246  final.push_back( it.toTrajectory() ); final.back().setSharedSeed(sharedSeed);
247  }
248 
249  result.swap(final);
250 
251  statCount.rebuilt(result.size());
252 
253 }
254 
258  const TrajectoryFilter* regionalCondition) const
259 {
260  if (theMeasurementTracker == 0) {
261  throw cms::Exception("LogicError") << "Asking to create trajectories to an un-initialized GroupedCkfTrajectoryBuilder.\nYou have to call clone(const MeasurementTrackerEvent *data) and then call trajectories on it instead.\n";
262  }
263 
264  statCount.seed();
265  //
266  // Build trajectory outwards from seed
267  //
268 
269  analyseSeed( seed);
270 
271  TempTrajectory const & startingTraj = createStartingTrajectory( seed);
272 
273  work_.clear();
274  const bool inOut = true;
275  groupedLimitedCandidates(seed, startingTraj, regionalCondition, forwardPropagator(seed), inOut, work_);
276  if ( work_.empty() ) return startingTraj;
277 
278  // cleaning now done here...
280  cleaner.clean(work_);
281 
282  boost::shared_ptr<const TrajectorySeed> pseed(new TrajectorySeed(seed));
283  for (auto const & it : work_) if (it.isValid()) {
284  result.push_back( it.toTrajectory() ); result.back().setSharedSeed(pseed);
285  }
286  work_.clear();
287  if (work_.capacity() > work_MaxSize_) { TempTrajectoryContainer().swap(work_); work_.reserve(work_MaxSize_/2); }
288 
289  analyseResult(result);
290 
291  LogDebug("CkfPattern")<< "GroupedCkfTrajectoryBuilder: returning result of size " << result.size();
292  statCount.traj(result.size());
293 
294 #ifdef VI_DEBUG
295  int kt=0;
296  for (auto const & traj : result) {
297 int chit[7]={};
298 for (auto const & tm : traj.measurements()) {
299  auto const & hit = tm.recHitR();
300  if (!hit.isValid()) ++chit[0];
301  if (hit.det()==nullptr) ++chit[1];
302  if ( trackerHitRTTI::isUndef(hit) ) continue;
303  if ( hit.dimension()!=2 ) {
304  ++chit[2];
305  } else {
306  auto const & thit = static_cast<BaseTrackerRecHit const&>(hit);
307  auto const & clus = thit.firstClusterRef();
308  if (clus.isPixel()) ++chit[3];
309  else if (thit.isMatched()) {
310  ++chit[4];
311  } else if (thit.isProjected()) {
312  ++chit[5];
313  } else {
314  ++chit[6];
315  }
316  }
317  }
318 
319 std::cout << "ckf " << kt++ << ": "; for (auto c:chit) std::cout << c <<'/'; std::cout<< std::endl;
320 }
321 #endif
322 
323  return startingTraj;
324 
325 }
326 
327 
328 void
330  TempTrajectory const& startingTraj,
331  const TrajectoryFilter* regionalCondition,
332  const Propagator* propagator,
333  bool inOut,
335 {
336  unsigned int nIter=1;
338  TempTrajectoryContainer newCand;
339  candidates.push_back( startingTraj);
340 
341  while ( !candidates.empty()) {
342 
343  newCand.clear();
344  for (TempTrajectoryContainer::iterator traj=candidates.begin();
345  traj!=candidates.end(); traj++) {
346  if ( !advanceOneLayer(seed, *traj, regionalCondition, propagator, inOut, newCand, result) ) {
347  LogDebug("CkfPattern")<< "GCTB: terminating after advanceOneLayer==false";
348  continue;
349  }
350 
351  LogDebug("CkfPattern")<<"newCand(1): after advanced one layer:\n"<<PrintoutHelper::dumpCandidates(newCand);
352 
353  if ((int)newCand.size() > theMaxCand) {
354  //ShowCand()(newCand);
355 
356  std::nth_element( newCand.begin(), newCand.begin()+theMaxCand, newCand.end(), GroupedTrajCandLess(theLostHitPenalty,theFoundHitBonus));
357  newCand.erase( newCand.begin()+theMaxCand, newCand.end());
358  }
359  LogDebug("CkfPattern")<<"newCand(2): after removing extra candidates.\n"<<PrintoutHelper::dumpCandidates(newCand);
360  }
361 
362  LogDebug("CkfPattern") << "newCand.size() at end = " << newCand.size();
363 /*
364  if (theIntermediateCleaning) {
365  candidates.clear();
366  candidates = groupedIntermediaryClean(newCand);
367  } else {
368  candidates.swap(newCand);
369  }
370 */
372 #ifdef STANDARD_INTERMEDIARYCLEAN
374 #else
375  groupedIntermediaryClean(newCand);
376 #endif
377 
378  }
379  candidates.swap(newCand);
380 
381  LogDebug("CkfPattern") <<"candidates(3): "<<result.size()<<" candidates after "<<nIter++<<" groupedCKF iteration: \n"
383  <<"\n "<<candidates.size()<<" running candidates are: \n"
384  <<PrintoutHelper::dumpCandidates(candidates);
385  }
386 }
387 
388 #ifdef EDM_ML_DEBUG
389 std::string whatIsTheNextStep(TempTrajectory const& traj , std::pair<TrajectoryStateOnSurface,std::vector<const DetLayer*> >& stateAndLayers){
390  std::stringstream buffer;
391  vector<const DetLayer*> & nl = stateAndLayers.second;
392  // #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
393  // #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
394  //B.M. TkLayerName layerName;
395  //B.M. buffer << "Started from " << layerName(traj.lastLayer())
396  const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
397  const ForwardDetLayer* sfdl = dynamic_cast<const ForwardDetLayer*>(traj.lastLayer());
398  if (sbdl) {
399  buffer << "Started from " << traj.lastLayer() << " r=" << sbdl->specificSurface().radius()
400  << " phi=" << sbdl->specificSurface().phi() << endl;
401  } else if (sfdl) {
402  buffer << "Started from " << traj.lastLayer() << " z " << sfdl->specificSurface().position().z()
403  << " phi " << sfdl->specificSurface().phi() << endl;
404  }
405  buffer << "Trying to go to";
406  for ( vector<const DetLayer*>::iterator il=nl.begin();
407  il!=nl.end(); il++){
408  //B.M. buffer << " " << layerName(*il) << " " << *il << endl;
409  const BarrelDetLayer* bdl = dynamic_cast<const BarrelDetLayer*>(*il);
410  const ForwardDetLayer* fdl = dynamic_cast<const ForwardDetLayer*>(*il);
411 
412  if (bdl) buffer << " r " << bdl->specificSurface().radius() << endl;
413  if (fdl) buffer << " z " << fdl->specificSurface().position().z() << endl;
414  //buffer << " " << *il << endl;
415  }
416  return buffer.str();
417 }
418 
419 std::string whatIsTheStateToUse(TrajectoryStateOnSurface &initial, TrajectoryStateOnSurface & stateToUse, const DetLayer * l){
420  std::stringstream buffer;
421  buffer << "GCTB: starting from "
422  << " r / phi / z = " << stateToUse.globalPosition().perp()
423  << " / " << stateToUse.globalPosition().phi()
424  << " / " << stateToUse.globalPosition().z()
425  << " , pt / phi / pz /charge = "
426  << stateToUse.globalMomentum().perp() << " / "
427  << stateToUse.globalMomentum().phi() << " / "
428  << stateToUse.globalMomentum().z() << " / "
429  << stateToUse.charge()
430  << " for layer at "<< l << endl;
431  buffer << " errors:";
432  for ( int i=0; i<5; i++ ) buffer << " " << sqrt(stateToUse.curvilinearError().matrix()(i,i));
433  buffer << endl;
434 
435  //buffer << "GCTB: starting from r / phi / z = " << initial.globalPosition().perp()
436  //<< " / " << initial.globalPosition().phi()
437  //<< " / " << initial.globalPosition().z() << " , pt / pz = "
438  //<< initial.globalMomentum().perp() << " / "
439  //<< initial.globalMomentum().z() << " for layer at "
440  //<< l << endl;
441  //buffer << " errors:";
442  //for ( int i=0; i<5; i++ ) buffer << " " << sqrt(initial.curvilinearError().matrix()(i,i));
443  //buffer << endl;
444  return buffer.str();
445 }
446 #endif
447 
448 bool
450  TempTrajectory& traj,
451  const TrajectoryFilter* regionalCondition,
452  const Propagator* propagator,
453  bool inOut,
454  TempTrajectoryContainer& newCand,
456 {
457  std::pair<TSOS,std::vector<const DetLayer*> > && stateAndLayers = findStateAndLayers(traj);
458 
459 
461  if(
462  //stateAndLayers.second.size()==0 &&
463  traj.lastLayer()->location()==0) {
464  float pt2 = stateAndLayers.first.globalMomentum().perp2();
466  pt2>(0.3f*0.3f)
467  )
468  stateAndLayers.second.push_back(traj.lastLayer());
469  }
470  }
471 
472  auto layerBegin = stateAndLayers.second.begin();
473  auto layerEnd = stateAndLayers.second.end();
474 
475  // if (nl.empty()) {
476  // addToResult(traj,result,inOut);
477  // return false;
478  // }
479 
480 #ifdef EDM_ML_DEBUG
481  LogDebug("CkfPattern")<<whatIsTheNextStep(traj, stateAndLayers);
482 #endif
483 
484  bool foundSegments(false);
485  bool foundNewCandidates(false);
486  for ( auto il=layerBegin; il!=layerEnd; il++) {
487 
488  TSOS stateToUse = stateAndLayers.first;
489 
490  double dPhiCacheForLoopersReconstruction(0);
491  if unlikely((*il)==traj.lastLayer()){
492 
494  // ------ For loopers reconstruction
495  //cout<<" self propagating in advanceOneLayer (for loopers) \n";
496  const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
497  if(sbdl){
498  HelixBarrelCylinderCrossing cylinderCrossing(stateToUse.globalPosition(),
499  stateToUse.globalMomentum(),
500  stateToUse.transverseCurvature(),
501  propagator->propagationDirection(),
502  sbdl->specificSurface());
503  if(!cylinderCrossing.hasSolution()) continue;
504  GlobalPoint starting = stateToUse.globalPosition();
505  GlobalPoint target1 = cylinderCrossing.position1();
506  GlobalPoint target2 = cylinderCrossing.position2();
507 
508  GlobalPoint farther = fabs(starting.phi()-target1.phi()) > fabs(starting.phi()-target2.phi()) ?
509  target1 : target2;
510 
511  const Bounds& bounds( sbdl->specificSurface().bounds());
512  float length = 0.5f*bounds.length();
513 
514  /*
515  cout << "starting: " << starting << endl;
516  cout << "target1: " << target1 << endl;
517  cout << "target2: " << target2 << endl;
518  cout << "dphi: " << (target1.phi()-target2.phi()) << endl;
519  cout << "length: " << length << endl;
520  */
521 
522  /*
523  float deltaZ = bounds.thickness()/2.f/fabs(tan(stateToUse.globalDirection().theta()) ) ;
524  if(stateToUse.hasError())
525  deltaZ += 3*sqrt(stateToUse.cartesianError().position().czz());
526  if( fabs(farther.z()) > length + deltaZ ) continue;
527  */
528  if(fabs(farther.z())*0.95f>length) continue;
529 
530  Geom::Phi<float> tmpDphi = target1.phi()-target2.phi();
531  if(std::abs(tmpDphi)>maxDPhiForLooperReconstruction) continue;
532  GlobalPoint target(0.5f*(target1.basicVector()+target2.basicVector()));
533  //cout << "target: " << target << endl;
534 
535 
536 
538  stateToUse = extrapolator.extrapolate(stateToUse, target, *propagator);
539  if (!stateToUse.isValid()) continue; //SK: consider trying the original? probably not
540 
541  //dPhiCacheForLoopersReconstruction = fabs(target1.phi()-target2.phi())*2.;
542  dPhiCacheForLoopersReconstruction = std::abs(tmpDphi);
543  traj.incrementLoops();
544  }else{ // not barrel
545  continue;
546  }
547  }else{ // loopers not requested (why else???)
548  // ------ For cosmics reconstruction
549  LogDebug("CkfPattern")<<" self propagating in advanceOneLayer.\n from: \n"<<stateToUse;
550  //self navigation case
551  // go to a middle point first
553  GlobalPoint center(0,0,0);
554  stateToUse = middle.extrapolate(stateToUse, center, *(forwardPropagator(seed)));
555 
556  if (!stateToUse.isValid()) continue;
557  LogDebug("CkfPattern")<<"to: "<<stateToUse;
558  }
559  } // last layer...
560 
561  //unsigned int maxCandidates = theMaxCand > 21 ? theMaxCand*2 : 42; //limit the number of returned segments
562  LayerMeasurements layerMeasurements(theMeasurementTracker->measurementTracker(), *theMeasurementTracker);
563  TrajectorySegmentBuilder layerBuilder(&layerMeasurements,
564  **il,*propagator,
567 
568 #ifdef EDM_ML_DEBUG
569  LogDebug("CkfPattern")<<whatIsTheStateToUse(stateAndLayers.first,stateToUse,*il);
570 #endif
571 
572  auto && segments= layerBuilder.segments(stateToUse);
573 
574  LogDebug("CkfPattern")<< "GCTB: number of segments = " << segments.size();
575 
576  if ( !segments.empty() ) foundSegments = true;
577 
578  for (auto is=segments.begin(); is!=segments.end(); is++ ) {
579  //
580  // assume "invalid hit only" segment is last in list
581  //
582  auto const & measurements = is->measurements();
583  if ( !theAlwaysUseInvalid && is!=segments.begin() && measurements.size()==1 &&
584  (measurements.front().recHit()->getType() == TrackingRecHit::missing) ) break;
585 
586 
587  //---- avoid to add the same hits more than once in the trajectory ----
588  bool toBeRejected(false);
589  for(auto revIt = measurements.rbegin(); revIt!=measurements.rend(); --revIt){
590  // int tmpCounter(0);
591  for(auto newTrajMeasIt = traj.measurements().rbegin();
592  newTrajMeasIt != traj.measurements().rend(); --newTrajMeasIt){
593  //if(tmpCounter==2) break;
594  if(revIt->recHitR().geographicalId()==newTrajMeasIt->recHitR().geographicalId()
595  && (revIt->recHitR().geographicalId() != DetId(0)) ){
596  toBeRejected=true;
597  goto rejected; //break; // see http://stackoverflow.com/questions/1257744/can-i-use-break-to-exit-multiple-nested-for-loops
598  }
599  // tmpCounter++;
600  }
601  }
602 
603  rejected:; // http://xkcd.com/292/
604  if(toBeRejected){
605 #ifdef VI_DEBUG
606  cout << "WARNING: neglect candidate because it contains the same hit twice \n";
607  cout << "-- discarded track's pt,eta,#found/lost: "
608  << traj.lastMeasurement().updatedState().globalMomentum().perp() << " , "
609  << traj.lastMeasurement().updatedState().globalMomentum().eta() << " , "
610  << traj.foundHits() << '/' << traj.lostHits() << "\n";
611 #endif
612  traj.setDPhiCacheForLoopersReconstruction(dPhiCacheForLoopersReconstruction);
613  continue; //Are we sure about this????
614  }
615  // ------------------------
616 
617  //
618  // create new candidate
619  //
620  TempTrajectory newTraj(traj);
621  traj.setDPhiCacheForLoopersReconstruction(dPhiCacheForLoopersReconstruction);
622  newTraj.join(*is);
623 
624  //std::cout << "DEBUG: newTraj after push found,lost: "
625  // << newTraj.foundHits() << " , "
626  // << newTraj.lostHits() << " , "
627  // << newTraj.measurements().size() << std::endl;
628 
629 
630 
631  //GIO// for ( vector<TM>::const_iterator im=measurements.begin();
632  //GIO// im!=measurements.end(); im++ ) newTraj.push(*im);
633  //if ( toBeContinued(newTraj,regionalCondition) ) { TOBE FIXED
634  if ( toBeContinued(newTraj, inOut) ) {
635  // Have added one more hit to track candidate
636 
637  LogDebug("CkfPattern")<<"GCTB: adding updated trajectory to candidates: inOut="<<inOut<<" hits="<<newTraj.foundHits();
638 
640  newCand.push_back(std::move(newTraj));
641  foundNewCandidates = true;
642  }
643  else {
644  // Have finished building this track. Check if it passes cuts.
645 
646  LogDebug("CkfPattern")<< "GCTB: adding completed trajectory to results if passes cuts: inOut="<<inOut<<" hits="<<newTraj.foundHits();
647  moveToResult(std::move(newTraj), result, inOut);
648  }
649  } // loop over segs
650  } // loop over layers
651 
652  if ( !foundSegments ){
653  LogDebug("CkfPattern")<< "GCTB: adding input trajectory to result";
654  if (stateAndLayers.second.size() > 0)
656  addToResult(traj, result, inOut);
657  }
658  return foundNewCandidates;
659 }
660 
661 namespace {
664  struct LayersInTraj {
665  static constexpr int N=3;
666  TempTrajectory * traj;
667  std::array<DetLayer const *,N> layers;
668  int tot;
669  void fill(TempTrajectory & t) {
670  traj = &t;
671  tot=0;
672  const TempTrajectory::DataContainer& measurements = traj->measurements();
673 
674  auto currl = layers[tot] = measurements.back().layer();
676  --ifirst;
678  im!=measurements.rend(); --im ) {
679  if ( im->layer()!=currl ) { ++tot; currl = im->layer(); if (tot<N) layers[tot] = currl;}
680  }
681  ++tot;
682  }
683 
684  //void verify() {
685  // for (vector<const DetLayer*>::const_iterator iter = result.begin(); iter != result.end(); iter++)
686  // if (!*iter) edm::LogWarning("CkfPattern")<< "Warning: null det layer!! ";
687  // }
688  };
689 }
690 
691 
692 //TempTrajectoryContainer
693 void
695 {
696  //if (theTrajectories.empty()) return TrajectoryContainer();
697  //TrajectoryContainer result;
698  if (theTrajectories.empty()) return;
699  //RecHitEqualByChannels recHitEqualByChannels(false, false);
700  LayersInTraj layers[theTrajectories.size()];
701  int ntraj=0;
702  for ( auto & t : theTrajectories) {
703  if ( t.isValid() && t.lastMeasurement().recHitR().isValid() )
704  layers[ntraj++].fill(t);
705  }
706 
707  if (ntraj<2) return;
708 
709  for (int ifirst=0; ifirst!=ntraj-1; ++ifirst) {
710  auto firstTraj = layers[ifirst].traj;
711  if (!firstTraj->isValid()) continue;
712  const TempTrajectory::DataContainer & firstMeasurements = firstTraj->measurements();
713 
714  int firstLayerSize = layers[ifirst].tot;
715  if ( firstLayerSize<4 ) continue;
716  auto const & firstLayers = layers[ifirst].layers;
717 
718  for (int isecond= ifirst+1; isecond!=ntraj; ++isecond) {
719  auto secondTraj = layers[isecond].traj;
720  if (!secondTraj->isValid()) continue;
721 
722  const TempTrajectory::DataContainer & secondMeasurements = secondTraj->measurements();
723 
724  int secondLayerSize = layers[isecond].tot;
725  //
726  // only candidates using the same last 3 layers are compared
727  //
728  if ( firstLayerSize!=secondLayerSize ) continue; // V.I. why equal???
729  auto const & secondLayers = layers[isecond].layers;
730  if ( firstLayers[0]!=secondLayers[0] ||
731  firstLayers[1]!=secondLayers[1] ||
732  firstLayers[2]!=secondLayers[2] ) continue;
733 
734  TempTrajectory::DataContainer::const_iterator im1 = firstMeasurements.rbegin();
735  TempTrajectory::DataContainer::const_iterator im2 = secondMeasurements.rbegin();
736  //
737  // check for identical hits in the last layer
738  //
739  bool unequal(false);
740  const DetLayer* layerPtr = firstLayers[0];
741  while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
742  if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr ) break;
743  if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
744  !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
746  unequal = true;
747  break;
748  }
749  --im1;
750  --im2;
751  }
752  if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
753  im1->layer()==layerPtr || im2->layer()==layerPtr || unequal ) continue;
754  //
755  // check for invalid hits in the layer -2
756  // compare only candidates with invalid / valid combination
757  //
758  layerPtr = firstLayers[1];
759  bool firstValid(true);
760  while ( im1!=firstMeasurements.rend()&&im1->layer()==layerPtr ) {
761  if ( !im1->recHit()->isValid() ) firstValid = false;
762  --im1;
763  }
764  bool secondValid(true);
765  while ( im2!=secondMeasurements.rend()&&im2->layer()==layerPtr ) {
766  if ( !im2->recHit()->isValid() ) secondValid = false;
767  --im2;
768  }
769  if ( !tkxor(firstValid,secondValid) ) continue;
770  //
771  // ask for identical hits in layer -3
772  //
773  unequal = false;
774  layerPtr = firstLayers[2];
775  while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
776  if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr ) break;
777  if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
778  !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
780  unequal = true;
781  break;
782  }
783  --im1;
784  --im2;
785  }
786  if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
787  im1->layer()==layerPtr || im2->layer()==layerPtr || unequal ) continue;
788 
789  if ( !firstValid ) {
790  firstTraj->invalidate();
791  break;
792  }
793  else {
794  secondTraj->invalidate(); // V.I. why break?
795  break;
796  }
797  } // second
798  } // first
799 /*
800  for (TempTrajectoryContainer::const_iterator it = theTrajectories.begin();
801  it != theTrajectories.end(); it++) {
802  if(it->isValid()) result.push_back( *it);
803  }
804 
805  return result;
806 */
807  theTrajectories.erase(std::remove_if( theTrajectories.begin(),theTrajectories.end(),
808  std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
809  // boost::bind(&TempTrajectory::isValid,_1)),
810  theTrajectories.end());
811 }
812 
813 
814 void
816  TempTrajectory const & startingTraj,
818 {
819  //
820  // Rebuilding of trajectories. Candidates are taken from result,
821  // which will be replaced with the solutions after rebuild
822  // (assume vector::swap is more efficient than building new container)
823  //
824  LogDebug("CkfPattern")<< "Starting to rebuild " << result.size() << " tracks";
825  //
826  // Fitter (need to create it here since the propagation direction
827  // might change between different starting trajectories)
828  //
829  auto hitCloner = static_cast<TkTransientTrackingRecHitBuilder const *>(hitBuilder())->cloner();
830  KFTrajectoryFitter fitter(backwardPropagator(seed),&updator(),&estimator(),3,nullptr,&hitCloner);
831  //
832  TrajectorySeed::range rseedHits = seed.recHits();
833  std::vector<const TrackingRecHit*> seedHits;
834  //seedHits.insert(seedHits.end(), rseedHits.first, rseedHits.second);
835  //for (TrajectorySeed::recHitContainer::const_iterator iter = rseedHits.first; iter != rseedHits.second; iter++){
836  // seedHits.push_back(&*iter);
837  //}
838 
839  //unsigned int nSeed(seedHits.size());
840  unsigned int nSeed(rseedHits.second-rseedHits.first);
841  //seedHits.reserve(nSeed);
842  TempTrajectoryContainer rebuiltTrajectories;
843 
844  for ( TempTrajectoryContainer::iterator it=result.begin();
845  it!=result.end(); it++ ) {
846 
847  // Refit - keep existing trajectory in case fit is not possible
848  // or fails
849  //
850 
851  auto && reFitted = backwardFit(*it,nSeed,fitter,seedHits);
852  if unlikely( !reFitted.isValid() ) {
853  rebuiltTrajectories.push_back(std::move(*it));
854  LogDebug("CkfPattern")<< "RebuildSeedingRegion skipped as backward fit failed";
855  // << "after reFitted.size() " << reFitted.size();
856  continue;
857  }
858  //LogDebug("CkfPattern")<<"after reFitted.size() " << reFitted.size();
859  //
860  // Rebuild seeding part. In case it fails: keep initial trajectory
861  // (better to drop it??)
862  //
863  int nRebuilt =
864  rebuildSeedingRegion (seed, seedHits,reFitted,rebuiltTrajectories);
865  // Loop over the last nRebuilt trajectories and propagate back the
866  // real cause that stopped the original in-out trajectory, since
867  // that's the one we want to monitor
868  for (size_t i = rebuiltTrajectories.size() - 1; i < rebuiltTrajectories.size() - nRebuilt - 1; --i) {
869  rebuiltTrajectories[i].setStopReason(it->stopReason());
870  }
871 
872  if ( nRebuilt==0 && !theKeepOriginalIfRebuildFails ) it->invalidate(); // won't use original in-out track
873 
874  if ( nRebuilt<0 ) rebuiltTrajectories.push_back(std::move(*it));
875  }
876  //
877  // Replace input trajectories with new ones
878  //
879  result.swap(rebuiltTrajectories);
880  result.erase(std::remove_if( result.begin(),result.end(),
881  std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
882  result.end());
883 }
884 
885 int
887  const std::vector<const TrackingRecHit*>& seedHits,
888  TempTrajectory& candidate,
890 {
891  //
892  // Starting from track found by in-out tracking phase, extrapolate it inwards through
893  // the seeding region if possible in towards smaller Tracker radii, searching for additional
894  // hits.
895  // The resulting trajectories are returned in result,
896  // the count is the return value.
897  //
898  TempTrajectoryContainer rebuiltTrajectories;
899 #ifdef DBG2_GCTB
900 /* const LayerFinderByDet layerFinder;
901  if ( !seedHits.empty() && seedHits.front().isValid() ) {
902  DetLayer* seedLayer = layerFinder(seedHits.front().det());
903  cout << "Seed hit at " << seedHits.front().globalPosition()
904  << " " << seedLayer << endl;
905  cout << "Started from "
906  << candidate.lastMeasurement().updatedState().globalPosition().perp() << " "
907  << candidate.lastMeasurement().updatedState().globalPosition().z() << endl;
908  pair<bool,TrajectoryStateOnSurface> layerComp(false,TrajectoryStateOnSurface());
909  if ( seedLayer ) layerComp =
910  seedLayer->compatible(candidate.lastMeasurement().updatedState(),
911  propagator(),estimator());
912  pair<bool,TrajectoryStateOnSurface> detComp =
913  seedHits.front().det().compatible(candidate.lastMeasurement().updatedState(),
914  propagator(),estimator());
915  cout << " layer compatibility = " << layerComp.first;
916  cout << " det compatibility = " << detComp.first;
917  if ( detComp.first ) {
918  cout << " estimate = "
919  << estimator().estimate(detComp.second,seedHits.front()).second ;
920  }
921  cout << endl;
922  }*/
923  cout << "Before backward building: #measurements = "
924  << candidate.measurements().size() ; //<< endl;;
925 #endif
926  //
927  // Use standard building with standard cuts. Maybe better to use different
928  // cuts from "forward" building (e.g. no check on nr. of invalid hits)?
929  //
930  const bool inOut = false;
931  groupedLimitedCandidates(seed, candidate, nullptr, backwardPropagator(seed), inOut, rebuiltTrajectories);
932 
933  LogDebug("CkfPattern")<<" After backward building: "<<PrintoutHelper::dumpCandidates(rebuiltTrajectories);
934 
935  //
936  // Check & count resulting candidates
937  //
938  int nrOfTrajectories(0);
939  bool orig_ok = false;
940  //const RecHitEqualByChannels recHitEqual(false,false);
941  //vector<TM> oldMeasurements(candidate.measurements());
942  for ( TempTrajectoryContainer::iterator it=rebuiltTrajectories.begin();
943  it!=rebuiltTrajectories.end(); it++ ) {
944 
945  TempTrajectory::DataContainer newMeasurements(it->measurements());
946  //
947  // Verify presence of seeding hits?
948  //
950  orig_ok = true;
951  // no hits found (and possibly some invalid hits discarded): drop track
952  if ( newMeasurements.size()<=candidate.measurements().size() ){
953  LogDebug("CkfPattern") << "newMeasurements.size()<=candidate.measurements().size()";
954  continue;
955  }
956  // verify presence of hits
957  //GIO//if ( !verifyHits(newMeasurements.begin()+candidate.measurements().size(),
958  //GIO// newMeasurements.end(),seedHits) ){
959  if ( !verifyHits(newMeasurements.rbegin(),
960  newMeasurements.size() - candidate.measurements().size(),
961  seedHits) ){
962  LogDebug("CkfPattern")<< "seed hits not found in rebuild";
963  continue;
964  }
965  }
966  //
967  // construct final trajectory in the right order
968  //
969  // save & count result
970  nrOfTrajectories++;
971  result.emplace_back(seed.direction(),seed.nHits());
972  TempTrajectory & reversedTrajectory = result.back();
973  reversedTrajectory.setNLoops(it->nLoops());
974  for (TempTrajectory::DataContainer::const_iterator im=newMeasurements.rbegin(), ed = newMeasurements.rend();
975  im != ed; --im ) {
976  reversedTrajectory.push(*im);
977  }
978 
979  LogDebug("CkgPattern")<<"New traj direction = " << reversedTrajectory.direction()<<"\n"
980  <<PrintoutHelper::dumpMeasurements(reversedTrajectory.measurements());
981  } // rebuiltTrajectories
982 
983  // If nrOfTrajectories = 0 and orig_ok = true, this means that a track was actually found on the
984  // out-in step (meeting those requirements) but did not have the seed hits in it.
985  // In this case when we return we will go ahead and use the original in-out track.
986 
987  // If nrOfTrajectories = 0 and orig_ok = false, this means that the out-in step failed to
988  // find any track. Two cases are a technical failure in fitting the original seed hits or
989  // because the track did not meet the out-in criteria (which may be stronger than the out-in
990  // criteria). In this case we will NOT allow the original in-out track to be used.
991 
992  if ( (nrOfTrajectories == 0) && orig_ok ) {
993  nrOfTrajectories = -1;
994  }
995  return nrOfTrajectories;
996 }
997 
1000  const TrajectoryFitter& fitter,
1001  std::vector<const TrackingRecHit*>& remainingHits) const
1002 {
1003  //
1004  // clear array of non-fitted hits
1005  //
1006  remainingHits.clear();
1007 
1008  LogDebug("CkfPattern")<<"nSeed " << nSeed << endl
1009  << "Old traj direction = " << candidate.direction() << endl
1011 
1012  //
1013  // backward fit trajectory.
1014  // (Will try to fit only hits outside the seeding region. However,
1015  // if there are not enough of these, it will also use the seeding hits).
1016  //
1017  // const unsigned int nHitAllMin(5);
1018  // const unsigned int nHit2dMin(2);
1019  unsigned int nHit(0); // number of valid hits after seeding region
1020  //unsigned int nHit2d(0); // number of valid hits after seeding region with 2D info
1021  // use all hits except the first n (from seed), but require minimum
1022  // specified in configuration.
1023  // Swapped over next two lines.
1024  unsigned int nHitMin = std::max(candidate.foundHits()-nSeed,theMinNrOfHitsForRebuild);
1025  // unsigned int nHitMin = oldMeasurements.size()-nSeed;
1026  // we want to rebuild only if the number of VALID measurements excluding the seed measurements is higher than the cut
1027  if unlikely(nHitMin<theMinNrOfHitsForRebuild) return TempTrajectory();
1028 
1029  LogDebug("CkfPattern")/* << "nHitMin " << nHitMin*/ <<"Sizes: " << candidate.measurements().size() << " / ";
1030  //
1031  // create input trajectory for backward fit
1032  //
1033  Trajectory fwdTraj(oppositeDirection(candidate.direction()));
1034  fwdTraj.setNLoops(candidate.nLoops());
1035  //const TrajectorySeed seed = TrajectorySeed(PTrajectoryStateOnDet(), TrajectorySeed::recHitContainer(), oppositeDirection(candidate.direction()));
1036  //Trajectory fwdTraj(seed, oppositeDirection(candidate.direction()));
1037 
1038  const DetLayer* bwdDetLayer[candidate.measurements().size()];
1039  int nl=0;
1040  for ( auto const & tm : candidate.measurements() ) {
1041  const TrackingRecHit* hit = tm.recHitR().hit();
1042  //
1043  // add hits until required number is reached
1044  //
1045  if ( nHit<nHitMin ){//|| nHit2d<theMinNrOf2dHitsForRebuild ) {
1046  fwdTraj.push(tm);
1047  bwdDetLayer[nl++]=tm.layer();
1048  //
1049  // count valid / 2D hits
1050  //
1051  if likely( hit->isValid() ) {
1052  nHit++;
1053  //if ( hit.isMatched() ||
1054  // hit.det().detUnits().front()->type().module()==pixel )
1055  //nHit2d++;
1056  }
1057  }
1058  //if (nHit==nHitMin) lastBwdDetLayer=im->layer();
1059  //
1060  // keep remaining (valid) hits for verification
1061  //
1062  else if ( hit->isValid() ) {
1063  //std::cout << "Adding a remaining hit" << std::endl;
1064  remainingHits.push_back(hit);
1065  }
1066  }
1067  //
1068  // Fit only if required number of valid hits can be used
1069  //
1070  if unlikely( nHit<nHitMin ) return TempTrajectory();
1071 
1072  //
1073  // Do the backward fit (important: start from scaled, not random cov. matrix!)
1074  //
1076  //cout << "firstTsos "<< firstTsos << endl;
1077  firstTsos.rescaleError(10.);
1078  //TrajectoryContainer bwdFitted(fitter.fit(fwdTraj.seed(),fwdTraj.recHits(),firstTsos));
1080  fwdTraj.recHits(),firstTsos);
1081  if unlikely(!bwdFitted.isValid()) return TempTrajectory();
1082 
1083 
1084  LogDebug("CkfPattern")<<"Obtained bwdFitted trajectory with measurement size " << bwdFitted.measurements().size();
1085  TempTrajectory fitted(fwdTraj.direction(),nSeed);
1086  fitted.setNLoops(fwdTraj.nLoops());
1087  vector<TM> const & tmsbf = bwdFitted.measurements();
1088  int iDetLayer=0;
1089  //this is ugly but the TM in the fitted track do not contain the DetLayer.
1090  //So we have to cache the detLayer pointers and replug them in.
1091  //For the backward building it would be enaugh to cache the last DetLayer,
1092  //but for the intermediary cleaning we need all
1093  for ( vector<TM>::const_iterator im=tmsbf.begin();im!=tmsbf.end(); im++ ) {
1094  fitted.emplace( (*im).forwardPredictedState(),
1095  (*im).backwardPredictedState(),
1096  (*im).updatedState(),
1097  (*im).recHit(),
1098  (*im).estimate(),
1099  bwdDetLayer[iDetLayer]
1100  );
1101 
1102  LogDebug("CkfPattern")<<PrintoutHelper::dumpMeasurement(*im);
1103  iDetLayer++;
1104  }
1105  /*
1106  TM lastMeas = bwdFitted.front().lastMeasurement();
1107  fitted.pop();
1108  fitted.push(TM(lastMeas.forwardPredictedState(),
1109  lastMeas.backwardPredictedState(),
1110  lastMeas.updatedState(),
1111  lastMeas.recHit(),
1112  lastMeas.estimate(),
1113  lastBwdDetLayer));
1114  */
1115 
1116 
1117  return fitted;
1118 }
1119 
1120 bool
1122  size_t maxDepth,
1123  const std::vector<const TrackingRecHit*>& hits) const
1124 {
1125  //
1126  // verify presence of the seeding hits
1127  //
1128  LogDebug("CkfPattern")<<"Checking for " << hits.size() << " hits in "
1129  << maxDepth << " measurements" << endl;
1130 
1131  auto rend = rbegin;
1132  while (maxDepth > 0) { --maxDepth; --rend; }
1133  for ( auto ir=hits.begin(); ir!=hits.end(); ir++ ) {
1134  // assume that all seeding hits are valid!
1135  bool foundHit(false);
1136  for ( auto im=rbegin; im!=rend; --im ) {
1137  if ( im->recHit()->isValid() && (*ir)->sharesInput(im->recHit()->hit(), TrackingRecHit::some) ) {
1138  foundHit = true;
1139  break;
1140  }
1141  }
1142  if ( !foundHit ) return false;
1143  }
1144  return true;
1145 }
1146 
1147 
1148 
1149 
#define LogDebug(id)
PropagationDirection direction() const
void setEvent_(const edm::Event &iEvent, const edm::EventSetup &iSetup) override
T getParameter(std::string const &) const
const_iterator rend() const
Definition: bqueue.h:164
virtual float length() const =0
static std::string dumpCandidates(collection &candidates)
void rebuildSeedingRegion(const TrajectorySeed &, TrajectoryContainer &result) const override
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
void clean(TempTrajectoryContainer &) const override
T perp() const
Definition: PV3DBase.h:72
void join(TempTrajectory &segment)
void rebuildTrajectories(TempTrajectory const &startingTraj, const TrajectorySeed &, TrajectoryContainer &result) const override
static void clean(TempTrajectoryContainer &tracks)
const Propagator * forwardPropagator(const TrajectorySeed &seed) const
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
Definition: print.cc:10
const CurvilinearTrajectoryError & curvilinearError() const
const DataContainer & measurements() const
virtual Location location() const =0
Which part of the detector (barrel, endcap)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
void setNLoops(signed char value)
Definition: Trajectory.h:349
void setNLoops(signed char value)
const TrajectoryStateUpdator * theUpdator
virtual void analyseSeed(const TrajectorySeed &seed) const
GlobalPoint globalPosition() const
ConstRecHitContainer recHits() const
Definition: Trajectory.h:204
virtual const BoundCylinder & specificSurface() const final
Extension of the interface.
int foundHits() const
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is rejected(acceptEvent retursns false).There are 3 relevant cases of types of criteria
static std::string dumpMeasurement(const TrajectoryMeasurement &tm)
static std::string dumpMeasurements(const std::vector< TrajectoryMeasurement > &v)
#define constexpr
signed char nLoops() const
Definition: Trajectory.h:347
virtual Trajectory fitOne(const Trajectory &traj, fitType type=standard) const =0
const TrajectoryMeasurement & lastMeasurement() const
PropagationDirection const & direction() const
Definition: Trajectory.cc:140
#define unlikely(x)
PropagationDirection direction() const
void setDPhiCacheForLoopersReconstruction(float dphi)
#define likely(x)
DataContainer const & measurements() const
Definition: Trajectory.h:196
const TransientTrackingRecHitBuilder * hitBuilder() const
virtual void analyseResult(const TrajectoryContainer &result) const
virtual PropagationDirection propagationDirection() const final
Definition: Propagator.h:151
static PropagationDirection oppositeDirection(PropagationDirection dir)
change of propagation direction
GroupedCkfTrajectoryBuilder(const edm::ParameterSet &conf, edm::ConsumesCollector &iC)
constructor from ParameterSet
bool verifyHits(TempTrajectory::DataContainer::const_iterator rbegin, size_t maxDepth, const std::vector< const TrackingRecHit * > &hits) const
Verifies presence of a RecHits in a range of TrajectoryMeasurements.
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
void groupedIntermediaryClean(TempTrajectoryContainer &theTrajectories) const
intermediate cleaning in the case of grouped measurements
const Chi2MeasurementEstimatorBase & estimator() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::pair< const_iterator, const_iterator > range
TempTrajectory backwardFit(TempTrajectory &candidate, unsigned int nSeed, const TrajectoryFitter &fitter, std::vector< const TrackingRecHit * > &remainingHits) const
const DetLayer * layer() const
bool advanceOneLayer(const TrajectorySeed &seed, TempTrajectory &traj, const TrajectoryFilter *regionalCondition, const Propagator *propagator, bool inOut, TempTrajectoryContainer &newCand, TempTrajectoryContainer &result) const
double f[11][100]
void addToResult(boost::shared_ptr< const TrajectorySeed > const &seed, TempTrajectory &traj, TrajectoryContainer &result, bool inOut=false) const
TempTrajectory buildTrajectories(const TrajectorySeed &seed, TrajectoryContainer &ret, const TrajectoryFilter *) const override
common part of both public trajectory building methods
const T & back() const
Definition: bqueue.h:161
TrajectoryContainer trajectories(const TrajectorySeed &) const override
set Event for the internal MeasurementTracker data member
void groupedLimitedCandidates(const TrajectorySeed &seed, TempTrajectory const &startingTraj, const TrajectoryFilter *regionalCondition, const Propagator *propagator, bool inOut, TempTrajectoryContainer &result) const
const_iterator rbegin() const
Definition: bqueue.h:163
bool isValid() const
StateAndLayers findStateAndLayers(const TrajectorySeed &seed, const TempTrajectory &traj) const
const MeasurementTrackerEvent * theMeasurementTracker
Definition: DetId.h:18
bool isValid() const
Definition: Trajectory.h:279
TrajectoryMeasurement const & firstMeasurement() const
Definition: Trajectory.h:187
virtual const BoundDisk & specificSurface() const final
#define N
Definition: blowfish.cc:9
std::vector< TempTrajectory > TempTrajectoryContainer
range recHits() const
bool isValid() const
const TrajectoryStateUpdator & updator() const
void moveToResult(TempTrajectory &&traj, TempTrajectoryContainer &result, bool inOut=false) const
T eta() const
Definition: PV3DBase.h:76
TrajectoryStateOnSurface extrapolate(const FreeTrajectoryState &fts, const GlobalPoint &vtx) const
extrapolation with default (=geometrical) propagator
unsigned int nHits() const
HLT enums.
const AlgebraicSymMatrix55 & matrix() const
GlobalVector globalMomentum() const
bool toBeContinued(TempTrajectory &traj, bool inOut=false) const
void setStopReason(StopReason s)
virtual OmniClusterRef const & firstClusterRef() const =0
bool tkxor(bool a, bool b) const
bool isUndef(TrackingRecHit const &hit)
const Propagator * backwardPropagator(const TrajectorySeed &seed) const
TrajectoryStateOnSurface const & updatedState() const
size_type size() const
Definition: bqueue.h:167
Definition: Bounds.h:22
signed char nLoops() const
const DetLayer * lastLayer() const
Redundant method, returns the layer of lastMeasurement() .
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:56
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:50
std::vector< Trajectory > TrajectoryContainer
def move(src, dest)
Definition: eostools.py:510
const Chi2MeasurementEstimatorBase * theEstimator
Definition: event.py:1
TempTrajectory createStartingTrajectory(const TrajectorySeed &seed) const
int lostHits() const
void push(const TrajectoryMeasurement &tm)