CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GroupedCkfTrajectoryBuilder.cc
Go to the documentation of this file.
1 
4 
5 
8 
23 
31 
32 // only included for RecHit comparison operator:
34 
35 // for looper reconstruction
39 
40 
41 #include <algorithm>
42 
43 using namespace std;
44 
45 //#define DBG2_GCTB
46 
47 //#define STANDARD_INTERMEDIARYCLEAN
48 
49 #ifdef STANDARD_INTERMEDIARYCLEAN
51 #endif
52 
53 /* ====== B.M. to be ported layer ===========
54 #ifdef DBG_GCTB
55 #include "RecoTracker/CkfPattern/src/ShowCand.h"
56 #endif
57 // #define DBG2_GCTB
58 #ifdef DBG2_GCTB
59 #include "RecoTracker/CkfPattern/src/SimIdPrinter.h"
60 #include "Tracker/TkDebugTools/interface/LayerFinderByDet.h"
61 #include "Tracker/TkLayout/interface/TkLayerName.h"
62 #endif
63 =================================== */
64 
65 
68  const TrajectoryStateUpdator* updator,
69  const Propagator* propagatorAlong,
70  const Propagator* propagatorOpposite,
71  const Chi2MeasurementEstimatorBase* estimator,
72  const TransientTrackingRecHitBuilder* recHitBuilder,
73  const MeasurementTracker* measurementTracker,
74  const TrajectoryFilter* filter,
75  const TrajectoryFilter* inOutFilter):
76 
77 
79  updator, propagatorAlong,propagatorOpposite,
80  estimator, recHitBuilder, measurementTracker, filter, inOutFilter)
81 {
82  // fill data members from parameters (eventually data members could be dropped)
83  //
84  theMaxCand = conf.getParameter<int>("maxCand");
85 
86  theLostHitPenalty = conf.getParameter<double>("lostHitPenalty");
87  theFoundHitBonus = conf.getParameter<double>("foundHitBonus");
88  theIntermediateCleaning = conf.getParameter<bool>("intermediateCleaning");
89  theAlwaysUseInvalid = conf.getParameter<bool>("alwaysUseInvalidHits");
90  theLockHits = conf.getParameter<bool>("lockHits");
91  theBestHitOnly = conf.getParameter<bool>("bestHitOnly");
93  theRequireSeedHitsInRebuild = conf.getParameter<bool>("requireSeedHitsInRebuild");
94  theMinNrOfHitsForRebuild = max(0,conf.getParameter<int>("minNrOfHitsForRebuild"));
95  maxPtForLooperReconstruction = conf.existsAs<double>("maxPtForLooperReconstruction") ?
96  conf.getParameter<double>("maxPtForLooperReconstruction") : 0;
97  maxDPhiForLooperReconstruction = conf.existsAs<double>("maxDPhiForLooperReconstruction") ?
98  conf.getParameter<double>("maxDPhiForLooperReconstruction") : 2.0;
99 
100 
101  /* ======= B.M. to be ported layer ===========
102  bool setOK = thePropagator->setMaxDirectionChange(1.6);
103  if (!setOK)
104  cout << "GroupedCkfTrajectoryBuilder WARNING: "
105  << "propagator does not support setMaxDirectionChange"
106  << endl;
107  // addStopCondition(theMinPtStopCondition);
108 
109  theConfigurableCondition = createAlgo<TrajectoryFilter>(componentConfig("StopCondition"));
110  ===================================== */
111 
112 }
113 
114 /*
115  void GroupedCkfTrajectoryBuilder::setEvent(const edm::Event& event) const
116  {
117  theMeasurementTracker->update(event);
118 }
119 */
120 
123 {
125  ret.reserve(10);
126  buildTrajectories(seed, ret, 0);
127  return ret;
128 }
129 
132  const TrackingRegion& region) const
133 {
135  ret.reserve(10);
136  RegionalTrajectoryFilter regionalCondition(region);
137  buildTrajectories(seed, ret, &regionalCondition);
138  return ret;
139 }
140 
141 void
143 {
144  buildTrajectories(seed,ret,0);
145 }
146 
147 void
150  const TrackingRegion& region) const
151 {
152  RegionalTrajectoryFilter regionalCondition(region);
153  buildTrajectories(seed,ret,&regionalCondition);
154 }
155 
156 void
158  TrajectoryContainer& result) const {
159  TempTrajectory startingTraj = createStartingTrajectory( seed);
161 
162  TrajectoryContainer final;
163 
164  work.reserve(result.size());
165  for (TrajectoryContainer::iterator traj=result.begin();
166  traj!=result.end(); ++traj) {
167  if(traj->isValid()) work.push_back(TempTrajectory(*traj));
168  }
169 
170  rebuildSeedingRegion(startingTraj,work);
171  final.reserve(work.size());
172 
173  for (TempTrajectoryContainer::iterator traj=work.begin();
174  traj!=work.end(); ++traj) {
175  final.push_back(traj->toTrajectory());
176  }
177 
178  result.swap(final);
179 
180 }
181 
182 void
185  const TrajectoryFilter* regionalCondition) const
186 {
187  //
188  // Build trajectory outwards from seed
189  //
190 
191  analyseSeed( seed);
192 
193  TempTrajectory startingTraj = createStartingTrajectory( seed);
194 
195  work_.clear();
196  const bool inOut = true;
197  groupedLimitedCandidates( startingTraj, regionalCondition, theForwardPropagator, inOut, work_);
198  if ( work_.empty() ) return ;
199 
200 
201 
202  /* rebuilding is de-coupled from standard building
203  //
204  // try to additional hits in the seeding region
205  //
206  if ( theMinNrOfHitsForRebuild>0 ) {
207  // reverse direction
208  //thePropagator->setPropagationDirection(oppositeDirection(seed.direction()));
209  // rebuild part of the trajectory
210  rebuildSeedingRegion(startingTraj,work);
211  }
212 
213  */
214 
215  result.reserve(work_.size());
216  for (TempTrajectoryContainer::const_iterator it = work_.begin(), ed = work_.end(); it != ed; ++it) {
217  result.push_back( it->toTrajectory() );
218  }
219 
220  work_.clear();
221  if (work_.capacity() > work_MaxSize_) { TempTrajectoryContainer().swap(work_); work_.reserve(work_MaxSize_/2); }
222 
223  analyseResult(result);
224 
225  LogDebug("CkfPattern")<< "GroupedCkfTrajectoryBuilder: returning result of size " << result.size();
226 
227 }
228 
229 
230 void
232  const TrajectoryFilter* regionalCondition,
233  const Propagator* propagator,
234  bool inOut,
236 {
237  unsigned int nIter=1;
238  TempTrajectoryContainer candidates;
239  TempTrajectoryContainer newCand;
240  candidates.push_back( startingTraj);
241 
242  while ( !candidates.empty()) {
243 
244  newCand.clear();
245  for (TempTrajectoryContainer::iterator traj=candidates.begin();
246  traj!=candidates.end(); traj++) {
247  if ( !advanceOneLayer(*traj, regionalCondition, propagator, inOut, newCand, result) ) {
248  LogDebug("CkfPattern")<< "GCTB: terminating after advanceOneLayer==false";
249  continue;
250  }
251 
252  LogDebug("CkfPattern")<<"newCand(1): after advanced one layer:\n"<<PrintoutHelper::dumpCandidates(newCand);
253 
254  if ((int)newCand.size() > theMaxCand) {
255  //ShowCand()(newCand);
256 
257  sort( newCand.begin(), newCand.end(), GroupedTrajCandLess(theLostHitPenalty,theFoundHitBonus));
258  newCand.erase( newCand.begin()+theMaxCand, newCand.end());
259  }
260  LogDebug("CkfPattern")<<"newCand(2): after removing extra candidates.\n"<<PrintoutHelper::dumpCandidates(newCand);
261  }
262 
263  LogDebug("CkfPattern") << "newCand.size() at end = " << newCand.size();
264 /*
265  if (theIntermediateCleaning) {
266  candidates.clear();
267  candidates = groupedIntermediaryClean(newCand);
268  } else {
269  candidates.swap(newCand);
270  }
271 */
273 #ifdef STANDARD_INTERMEDIARYCLEAN
275 #else
276  groupedIntermediaryClean(newCand);
277 #endif
278 
279  }
280  candidates.swap(newCand);
281 
282  LogDebug("CkfPattern") <<"candidates(3): "<<result.size()<<" candidates after "<<nIter++<<" groupedCKF iteration: \n"
284  <<"\n "<<candidates.size()<<" running candidates are: \n"
285  <<PrintoutHelper::dumpCandidates(candidates);
286  }
287 }
288 
289 std::string whatIsTheNextStep(TempTrajectory& traj , std::pair<TrajectoryStateOnSurface,std::vector<const DetLayer*> >& stateAndLayers){
290  std::stringstream buffer;
291  vector<const DetLayer*> & nl = stateAndLayers.second;
294  //B.M. TkLayerName layerName;
295  //B.M. buffer << "Started from " << layerName(traj.lastLayer())
296  const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
297  const ForwardDetLayer* sfdl = dynamic_cast<const ForwardDetLayer*>(traj.lastLayer());
298  if (sbdl) {
299  buffer << "Started from " << traj.lastLayer() << " r=" << sbdl->specificSurface().radius()
300  << " phi=" << sbdl->specificSurface().phi() << endl;
301  } else if (sfdl) {
302  buffer << "Started from " << traj.lastLayer() << " z " << sfdl->specificSurface().position().z()
303  << " phi " << sfdl->specificSurface().phi() << endl;
304  }
305  buffer << "Trying to go to";
306  for ( vector<const DetLayer*>::iterator il=nl.begin();
307  il!=nl.end(); il++){
308  //B.M. buffer << " " << layerName(*il) << " " << *il << endl;
309  const BarrelDetLayer* bdl = dynamic_cast<const BarrelDetLayer*>(*il);
310  const ForwardDetLayer* fdl = dynamic_cast<const ForwardDetLayer*>(*il);
311 
312  if (bdl) buffer << " r " << bdl->specificSurface().radius() << endl;
313  if (fdl) buffer << " z " << fdl->specificSurface().position().z() << endl;
314  //buffer << " " << *il << endl;
315  }
316  return buffer.str();
317 }
318 
320  std::stringstream buffer;
321  buffer << "GCTB: starting from "
322  << " r / phi / z = " << stateToUse.globalPosition().perp()
323  << " / " << stateToUse.globalPosition().phi()
324  << " / " << stateToUse.globalPosition().z()
325  << " , pt / phi / pz /charge = "
326  << stateToUse.globalMomentum().perp() << " / "
327  << stateToUse.globalMomentum().phi() << " / "
328  << stateToUse.globalMomentum().z() << " / "
329  << stateToUse.charge()
330  << " for layer at "<< l << endl;
331  buffer << " errors:";
332  for ( int i=0; i<5; i++ ) buffer << " " << sqrt(stateToUse.curvilinearError().matrix()(i,i));
333  buffer << endl;
334 
335  //buffer << "GCTB: starting from r / phi / z = " << initial.globalPosition().perp()
336  //<< " / " << initial.globalPosition().phi()
337  //<< " / " << initial.globalPosition().z() << " , pt / pz = "
338  //<< initial.globalMomentum().perp() << " / "
339  //<< initial.globalMomentum().z() << " for layer at "
340  //<< l << endl;
341  //buffer << " errors:";
342  //for ( int i=0; i<5; i++ ) buffer << " " << sqrt(initial.curvilinearError().matrix()(i,i));
343  //buffer << endl;
344  return buffer.str();
345 }
346 
347 
348 bool
350  const TrajectoryFilter* regionalCondition,
351  const Propagator* propagator,
352  bool inOut,
353  TempTrajectoryContainer& newCand,
355 {
356  std::pair<TSOS,std::vector<const DetLayer*> > stateAndLayers = findStateAndLayers(traj);
358  if(
359  //stateAndLayers.second.size()==0 &&
360  traj.lastLayer()->location()==0 &&
361  stateAndLayers.first.globalMomentum().perp()<maxPtForLooperReconstruction &&
362  stateAndLayers.first.globalMomentum().perp()>0.3)
363  stateAndLayers.second.push_back(traj.lastLayer());
364  }
365 
366  vector<const DetLayer*>::iterator layerBegin = stateAndLayers.second.begin();
367  vector<const DetLayer*>::iterator layerEnd = stateAndLayers.second.end();
368 
369  // if (nl.empty()) {
370  // addToResult(traj,result,inOut);
371  // return false;
372  // }
373 
374  LogDebug("CkfPattern")<<whatIsTheNextStep(traj, stateAndLayers);
375 
376  bool foundSegments(false);
377  bool foundNewCandidates(false);
378  for ( vector<const DetLayer*>::iterator il=layerBegin;
379  il!=layerEnd; il++) {
380 
381  TSOS stateToUse = stateAndLayers.first;
382 
383  double dPhiCacheForLoopersReconstruction(0);
384  if ((*il)==traj.lastLayer()){
386  // ------ For loopers reconstruction
387  //cout<<" self propagating in advanceOneLayer (for loopers) \n";
388  const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
389  if(sbdl){
390  HelixBarrelCylinderCrossing cylinderCrossing(stateToUse.globalPosition(),
391  stateToUse.globalMomentum(),
392  stateToUse.transverseCurvature(),
393  propagator->propagationDirection(),
394  sbdl->specificSurface());
395  if(!cylinderCrossing.hasSolution()) continue;
396  GlobalPoint starting = stateToUse.globalPosition();
397  GlobalPoint target1 = cylinderCrossing.position1();
398  GlobalPoint target2 = cylinderCrossing.position2();
399 
400  GlobalPoint farther = fabs(starting.phi()-target1.phi()) > fabs(starting.phi()-target2.phi()) ?
401  target1 : target2;
402 
403  const Bounds& bounds( sbdl->specificSurface().bounds());
404  float length = bounds.length() / 2.f;
405 
406  /*
407  cout << "starting: " << starting << endl;
408  cout << "target1: " << target1 << endl;
409  cout << "target2: " << target2 << endl;
410  cout << "dphi: " << (target1.phi()-target2.phi()) << endl;
411  cout << "length: " << length << endl;
412  */
413 
414  /*
415  float deltaZ = bounds.thickness()/2.f/fabs(tan(stateToUse.globalDirection().theta()) ) ;
416  if(stateToUse.hasError())
417  deltaZ += 3*sqrt(stateToUse.cartesianError().position().czz());
418  if( fabs(farther.z()) > length + deltaZ ) continue;
419  */
420  if(fabs(farther.z())*0.95>length) continue;
421 
422  Geom::Phi<double> tmpDphi = target1.phi()-target2.phi();
423  if(fabs(tmpDphi)>maxDPhiForLooperReconstruction) continue;
424  GlobalPoint target((target1.x()+target2.x())/2,
425  (target1.y()+target2.y())/2,
426  (target1.z()+target2.z())/2);
427 
428  //cout << "target: " << target << endl;
429 
430 
431 
433  stateToUse = extrapolator.extrapolate(stateToUse, target, *propagator);
434  if (!stateToUse.isValid()) continue; //SK: consider trying the original? probably not
435 
436  //dPhiCacheForLoopersReconstruction = fabs(target1.phi()-target2.phi())*2.;
437  dPhiCacheForLoopersReconstruction = fabs(tmpDphi);
438  traj.incrementLoops();
439  }else{
440  continue;
441  }
442  }else{
443  // ------ For cosmics reconstruction
444  LogDebug("CkfPattern")<<" self propagating in advanceOneLayer.\n from: \n"<<stateToUse;
445  //self navigation case
446  // go to a middle point first
448  GlobalPoint center(0,0,0);
449  stateToUse = middle.extrapolate(stateToUse, center, *theForwardPropagator);
450 
451  if (!stateToUse.isValid()) continue;
452  LogDebug("CkfPattern")<<"to: "<<stateToUse;
453  }
454  }
455 
456  unsigned int maxCandidates = theMaxCand > 21 ? theMaxCand*2 : 42; //limit the number of returned segments
459  **il,*propagator,
461  theLockHits,theBestHitOnly, maxCandidates);
462 
463  LogDebug("CkfPattern")<<whatIsTheStateToUse(stateAndLayers.first,stateToUse,*il);
464 
465  TempTrajectoryContainer segments=
466  layerBuilder.segments(stateToUse);
467 
468  LogDebug("CkfPattern")<< "GCTB: number of segments = " << segments.size();
469 
470  if ( !segments.empty() ) foundSegments = true;
471 
472  for ( TempTrajectoryContainer::const_iterator is=segments.begin();
473  is!=segments.end(); is++ ) {
474  //
475  // assume "invalid hit only" segment is last in list
476  //
477  const TempTrajectory::DataContainer & measurements = is->measurements();
478  if ( !theAlwaysUseInvalid && is!=segments.begin() && measurements.size()==1 &&
479  (measurements.front().recHit()->getType() == TrackingRecHit::missing) ) break;
480  //
481  // create new candidate
482  //
483  TempTrajectory newTraj(traj);
484  traj.setDPhiCacheForLoopersReconstruction(dPhiCacheForLoopersReconstruction);
485 
486  //---- avoid to add the same hits more than once in the trajectory ----
487  bool toBeRejected(false);
488  for(const TempTrajectory::DataContainer::const_iterator revIt = measurements.rbegin();
489  revIt!=measurements.rend(); --revIt){
490  int tmpCounter(0);
491  for(const TempTrajectory::DataContainer::const_iterator newTrajMeasIt = newTraj.measurements().rbegin();
492  newTrajMeasIt != newTraj.measurements().rend(); --newTrajMeasIt){
493  //if(tmpCounter==2) break;
494  if(revIt->recHit()->geographicalId()==newTrajMeasIt->recHit()->geographicalId()){
495  toBeRejected=true;
496  break;
497  }
498  tmpCounter++;
499  }
500  }
501 
502  if(!toBeRejected){
503  //newTraj.push(*is);
504  //std::cout << "DEBUG: newTraj after push found,lost: "
505  // << newTraj.foundHits() << " , "
506  // << newTraj.lostHits() << " , "
507  // << newTraj.measurements().size() << std::endl;
508  }else{
509  /*cout << "WARNING: neglect candidate because it contains the same hit twice \n";
510  cout << "-- discarded track's pt,eta,#found: "
511  << newTraj.lastMeasurement().updatedState().globalMomentum().perp() << " , "
512  << newTraj.lastMeasurement().updatedState().globalMomentum().eta() << " , "
513  << newTraj.foundHits() << "\n";
514  */
515  continue; //Are we sure about this????
516  }
517  // ------------------------
518 
519 
520  newTraj.push(*is);
521  //GIO// for ( vector<TM>::const_iterator im=measurements.begin();
522  //GIO// im!=measurements.end(); im++ ) newTraj.push(*im);
523  //if ( toBeContinued(newTraj,regionalCondition) ) { TOBE FIXED
524  if ( toBeContinued(newTraj, inOut) ) {
525  // Have added one more hit to track candidate
526 
527  LogDebug("CkfPattern")<<"GCTB: adding updated trajectory to candidates: inOut="<<inOut<<" hits="<<newTraj.foundHits();
528 
529  newCand.push_back(newTraj);
530  foundNewCandidates = true;
531  }
532  else {
533  // Have finished building this track. Check if it passes cuts.
534 
535  LogDebug("CkfPattern")<< "GCTB: adding completed trajectory to results if passes cuts: inOut="<<inOut<<" hits="<<newTraj.foundHits();
536 
537  addToResult(newTraj, result, inOut);
538  }
539  }
540  }
541 
542  if ( !foundSegments ){
543  LogDebug("CkfPattern")<< "GCTB: adding input trajectory to result";
544  addToResult(traj, result, inOut);
545  }
546  return foundNewCandidates;
547 }
548 
549 //TempTrajectoryContainer
550 void
552 {
553  //if (theTrajectories.empty()) return TrajectoryContainer();
554  //TrajectoryContainer result;
555  if (theTrajectories.empty()) return;
556  //RecHitEqualByChannels recHitEqualByChannels(false, false);
557  int firstLayerSize, secondLayerSize;
558  vector<const DetLayer*> firstLayers, secondLayers;
559 
560  for (TempTrajectoryContainer::iterator firstTraj=theTrajectories.begin();
561  firstTraj!=(theTrajectories.end()-1); firstTraj++) {
562 
563  if ( (!firstTraj->isValid()) ||
564  (!firstTraj->lastMeasurement().recHit()->isValid()) ) continue;
565  const TempTrajectory::DataContainer & firstMeasurements = firstTraj->measurements();
566  layers(firstMeasurements, firstLayers);
567  firstLayerSize = firstLayers.size();
568  if ( firstLayerSize<4 ) continue;
569 
570  for (TempTrajectoryContainer::iterator secondTraj=(firstTraj+1);
571  secondTraj!=theTrajectories.end(); secondTraj++) {
572 
573  if ( (!secondTraj->isValid()) ||
574  (!secondTraj->lastMeasurement().recHit()->isValid()) ) continue;
575  const TempTrajectory::DataContainer & secondMeasurements = secondTraj->measurements();
576  layers(secondMeasurements, secondLayers);
577  secondLayerSize = secondLayers.size();
578  //
579  // only candidates using the same last 3 layers are compared
580  //
581  if ( firstLayerSize!=secondLayerSize ) continue;
582  if ( firstLayers[0]!=secondLayers[0] ||
583  firstLayers[1]!=secondLayers[1] ||
584  firstLayers[2]!=secondLayers[2] ) continue;
585 
586  TempTrajectory::DataContainer::const_iterator im1 = firstMeasurements.rbegin();
587  TempTrajectory::DataContainer::const_iterator im2 = secondMeasurements.rbegin();
588  //
589  // check for identical hits in the last layer
590  //
591  bool unequal(false);
592  const DetLayer* layerPtr = firstLayers[0];
593  while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
594  if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr ) break;
595  if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
596  !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
598  unequal = true;
599  break;
600  }
601  --im1;
602  --im2;
603  }
604  if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
605  im1->layer()==layerPtr || im2->layer()==layerPtr || unequal ) continue;
606  //
607  // check for invalid hits in the layer -2
608  // compare only candidates with invalid / valid combination
609  //
610  layerPtr = firstLayers[1];
611  bool firstValid(true);
612  while ( im1!=firstMeasurements.rend()&&im1->layer()==layerPtr ) {
613  if ( !im1->recHit()->isValid() ) firstValid = false;
614  --im1;
615  }
616  bool secondValid(true);
617  while ( im2!=secondMeasurements.rend()&&im2->layer()==layerPtr ) {
618  if ( !im2->recHit()->isValid() ) secondValid = false;
619  --im2;
620  }
621  if ( !tkxor(firstValid,secondValid) ) continue;
622  //
623  // ask for identical hits in layer -3
624  //
625  unequal = false;
626  layerPtr = firstLayers[2];
627  while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
628  if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr ) break;
629  if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
630  !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
632  unequal = true;
633  break;
634  }
635  --im1;
636  --im2;
637  }
638  if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
639  im1->layer()==layerPtr || im2->layer()==layerPtr || unequal ) continue;
640 
641  if ( !firstValid ) {
642  firstTraj->invalidate();
643  break;
644  }
645  else {
646  secondTraj->invalidate();
647  break;
648  }
649  }
650  }
651 /*
652  for (TempTrajectoryContainer::const_iterator it = theTrajectories.begin();
653  it != theTrajectories.end(); it++) {
654  if(it->isValid()) result.push_back( *it);
655  }
656 
657  return result;
658 */
659  theTrajectories.erase(std::remove_if( theTrajectories.begin(),theTrajectories.end(),
660  std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
661  // boost::bind(&TempTrajectory::isValid,_1)),
662  theTrajectories.end());
663 }
664 
665 void
667  vector<const DetLayer*> &result) const
668 {
669  result.clear();
670 
671  if ( measurements.empty() ) return ;
672 
673  result.push_back(measurements.back().layer());
675  --ifirst;
677  im!=measurements.rend(); --im ) {
678  if ( im->layer()!=result.back() ) result.push_back(im->layer());
679  }
680 
681  for (vector<const DetLayer*>::const_iterator iter = result.begin(); iter != result.end(); iter++){
682  if (!*iter) edm::LogWarning("CkfPattern")<< "Warning: null det layer!! ";
683  }
684 }
685 
686 void
689 {
690  //
691  // Rebuilding of trajectories. Candidates are taken from result,
692  // which will be replaced with the solutions after rebuild
693  // (assume vector::swap is more efficient than building new container)
694  //
695  LogDebug("CkfPattern")<< "Starting to rebuild " << result.size() << " tracks";
696  //
697  // Fitter (need to create it here since the propagation direction
698  // might change between different starting trajectories)
699  //
701  //
702  TempTrajectoryContainer reFitted;
703  TrajectorySeed::range rseedHits = startingTraj.seed().recHits();
704  std::vector<const TrackingRecHit*> seedHits;
705  //seedHits.insert(seedHits.end(), rseedHits.first, rseedHits.second);
706  //for (TrajectorySeed::recHitContainer::const_iterator iter = rseedHits.first; iter != rseedHits.second; iter++){
707  // seedHits.push_back(&*iter);
708  //}
709 
710  //unsigned int nSeed(seedHits.size());
711  unsigned int nSeed(rseedHits.second-rseedHits.first);
712  //seedHits.reserve(nSeed);
713  TempTrajectoryContainer rebuiltTrajectories;
714  for ( TempTrajectoryContainer::iterator it=result.begin();
715  it!=result.end(); it++ ) {
716  //
717  // skip candidates which are not exceeding the seed size
718  // (e.g. because no Tracker layers outside seeding region)
719  //
720 
721  if ( it->measurements().size()<=startingTraj.measurements().size() ) {
722  rebuiltTrajectories.push_back(*it);
723  LogDebug("CkfPattern")<< "RebuildSeedingRegion skipped as in-out trajectory does not exceed seed size.";
724  continue;
725  }
726  //
727  // Refit - keep existing trajectory in case fit is not possible
728  // or fails
729  //
730 
731  backwardFit(*it,nSeed,fitter,reFitted,seedHits);
732  if ( reFitted.size()!=1 ) {
733  rebuiltTrajectories.push_back(*it);
734  LogDebug("CkfPattern")<< "RebuildSeedingRegion skipped as backward fit failed";
735  // << "after reFitted.size() " << reFitted.size();
736  continue;
737  }
738  //LogDebug("CkfPattern")<<"after reFitted.size() " << reFitted.size();
739  //
740  // Rebuild seeding part. In case it fails: keep initial trajectory
741  // (better to drop it??)
742  //
743  int nRebuilt =
744  rebuildSeedingRegion (seedHits,reFitted.front(),rebuiltTrajectories);
745 
746  if ( nRebuilt==0 ) it->invalidate(); // won't use original in-out track
747 
748  if ( nRebuilt<=0 ) rebuiltTrajectories.push_back(*it);
749 
750  }
751  //
752  // Replace input trajectories with new ones
753  //
754  result.swap(rebuiltTrajectories);
755  result.erase(std::remove_if( result.begin(),result.end(),
756  std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
757  result.end());
758 }
759 
760 int
761 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const std::vector<const TrackingRecHit*>& seedHits,
762  TempTrajectory& candidate,
764 {
765  //
766  // Starting from track found by in-out tracking phase, extrapolate it inwards through
767  // the seeding region if possible in towards smaller Tracker radii, searching for additional
768  // hits.
769  // The resulting trajectories are returned in result,
770  // the count is the return value.
771  //
772  TempTrajectoryContainer rebuiltTrajectories;
773 #ifdef DBG2_GCTB
774 /* const LayerFinderByDet layerFinder;
775  if ( !seedHits.empty() && seedHits.front().isValid() ) {
776  DetLayer* seedLayer = layerFinder(seedHits.front().det());
777  cout << "Seed hit at " << seedHits.front().globalPosition()
778  << " " << seedLayer << endl;
779  cout << "Started from "
780  << candidate.lastMeasurement().updatedState().globalPosition().perp() << " "
781  << candidate.lastMeasurement().updatedState().globalPosition().z() << endl;
782  pair<bool,TrajectoryStateOnSurface> layerComp(false,TrajectoryStateOnSurface());
783  if ( seedLayer ) layerComp =
784  seedLayer->compatible(candidate.lastMeasurement().updatedState(),
785  propagator(),estimator());
786  pair<bool,TrajectoryStateOnSurface> detComp =
787  seedHits.front().det().compatible(candidate.lastMeasurement().updatedState(),
788  propagator(),estimator());
789  cout << " layer compatibility = " << layerComp.first;
790  cout << " det compatibility = " << detComp.first;
791  if ( detComp.first ) {
792  cout << " estimate = "
793  << estimator().estimate(detComp.second,seedHits.front()).second ;
794  }
795  cout << endl;
796  }*/
797  cout << "Before backward building: #measurements = "
798  << candidate.measurements().size() ; //<< endl;;
799 #endif
800  //
801  // Use standard building with standard cuts. Maybe better to use different
802  // cuts from "forward" building (e.g. no check on nr. of invalid hits)?
803  //
804  const bool inOut = false;
805  groupedLimitedCandidates(candidate, (const TrajectoryFilter*)0, theBackwardPropagator, inOut, rebuiltTrajectories);
806 
807  LogDebug("CkfPattern")<<" After backward building: "<<PrintoutHelper::dumpCandidates(rebuiltTrajectories);
808 
809  //
810  // Check & count resulting candidates
811  //
812  int nrOfTrajectories(0);
813  bool orig_ok = false;
814  //const RecHitEqualByChannels recHitEqual(false,false);
815  //vector<TM> oldMeasurements(candidate.measurements());
816  for ( TempTrajectoryContainer::iterator it=rebuiltTrajectories.begin();
817  it!=rebuiltTrajectories.end(); it++ ) {
818 
819  TempTrajectory::DataContainer newMeasurements(it->measurements());
820  //
821  // Verify presence of seeding hits?
822  //
824  orig_ok = true;
825  // no hits found (and possibly some invalid hits discarded): drop track
826  if ( newMeasurements.size()<=candidate.measurements().size() ){
827  LogDebug("CkfPattern") << "newMeasurements.size()<=candidate.measurements().size()";
828  continue;
829  }
830  // verify presence of hits
831  //GIO//if ( !verifyHits(newMeasurements.begin()+candidate.measurements().size(),
832  //GIO// newMeasurements.end(),seedHits) ){
833  if ( !verifyHits(newMeasurements.rbegin(),
834  newMeasurements.size() - candidate.measurements().size(),
835  seedHits) ){
836  LogDebug("CkfPattern")<< "seed hits not found in rebuild";
837  continue;
838  }
839  }
840  //
841  // construct final trajectory in the right order
842  //
843  TempTrajectory reversedTrajectory(it->seed(),it->seed().direction());
844  reversedTrajectory.setNLoops(it->nLoops());
845  for (TempTrajectory::DataContainer::const_iterator im=newMeasurements.rbegin(), ed = newMeasurements.rend();
846  im != ed; --im ) {
847  reversedTrajectory.push(*im);
848  }
849  // save & count result
850  result.push_back(reversedTrajectory);
851  nrOfTrajectories++;
852 
853  LogDebug("CkgPattern")<<"New traj direction = " << reversedTrajectory.direction()<<"\n"
854  <<PrintoutHelper::dumpMeasurements(reversedTrajectory.measurements());
855  }
856  // If nrOfTrajectories = 0 and orig_ok = true, this means that a track was actually found on the
857  // out-in step (meeting those requirements) but did not have the seed hits in it.
858  // In this case when we return we will go ahead and use the original in-out track.
859 
860  // If nrOfTrajectories = 0 and orig_ok = false, this means that the out-in step failed to
861  // find any track. Two cases are a technical failure in fitting the original seed hits or
862  // because the track did not meet the out-in criteria (which may be stronger than the out-in
863  // criteria). In this case we will NOT allow the original in-out track to be used.
864 
865  if ( (nrOfTrajectories == 0) && orig_ok ) {
866  nrOfTrajectories = -1;
867  }
868  return nrOfTrajectories;
869 }
870 
871 void
873  const TrajectoryFitter& fitter,
874  TempTrajectoryContainer& fittedTracks,
875  std::vector<const TrackingRecHit*>& remainingHits) const
876 {
877  //
878  // clear array of non-fitted hits
879  //
880  remainingHits.clear();
881  fittedTracks.clear();
882  //
883  // skip candidates which are not exceeding the seed size
884  // (e.g. Because no Tracker layers exist outside seeding region)
885  //
886  if ( candidate.measurements().size()<=nSeed ) {
887  fittedTracks.clear();
888  return;
889  }
890 
891  LogDebug("CkfPattern")<<"nSeed " << nSeed << endl
892  << "Old traj direction = " << candidate.direction() << endl
894 
895  //
896  // backward fit trajectory.
897  // (Will try to fit only hits outside the seeding region. However,
898  // if there are not enough of these, it will also use the seeding hits).
899  //
900  TempTrajectory::DataContainer oldMeasurements(candidate.measurements());
901 // int nOld(oldMeasurements.size());
902 // const unsigned int nHitAllMin(5);
903 // const unsigned int nHit2dMin(2);
904  unsigned int nHit(0); // number of valid hits after seeding region
905  //unsigned int nHit2d(0); // number of valid hits after seeding region with 2D info
906  // use all hits except the first n (from seed), but require minimum
907  // specified in configuration.
908  // Swapped over next two lines.
909  unsigned int nHitMin = max(candidate.foundHits()-nSeed,theMinNrOfHitsForRebuild);
910  // unsigned int nHitMin = oldMeasurements.size()-nSeed;
911  // we want to rebuild only if the number of VALID measurements excluding the seed measurements is higher than the cut
912  if (nHitMin<theMinNrOfHitsForRebuild){
913  fittedTracks.clear();
914  return;
915  }
916 
917  LogDebug("CkfPattern")/* << "nHitMin " << nHitMin*/ <<"Sizes: " << oldMeasurements.size() << " / ";
918  //
919  // create input trajectory for backward fit
920  //
921  Trajectory fwdTraj(candidate.seed(),oppositeDirection(candidate.direction()));
922  fwdTraj.setNLoops(candidate.nLoops());
923  //const TrajectorySeed seed = TrajectorySeed(PTrajectoryStateOnDet(), TrajectorySeed::recHitContainer(), oppositeDirection(candidate.direction()));
924  //Trajectory fwdTraj(seed, oppositeDirection(candidate.direction()));
925  std::vector<const DetLayer*> bwdDetLayer;
926  for ( TempTrajectory::DataContainer::const_iterator im=oldMeasurements.rbegin();
927  im!=oldMeasurements.rend(); --im) {
928  const TrackingRecHit* hit = im->recHit()->hit();
929  //
930  // add hits until required number is reached
931  //
932  if ( nHit<nHitMin ){//|| nHit2d<theMinNrOf2dHitsForRebuild ) {
933  fwdTraj.push(*im);
934  bwdDetLayer.push_back(im->layer());
935  //
936  // count valid / 2D hits
937  //
938  if ( hit->isValid() ) {
939  nHit++;
940  //if ( hit.isMatched() ||
941  // hit.det().detUnits().front()->type().module()==pixel )
942  //nHit2d++;
943  }
944  }
945  //if (nHit==nHitMin) lastBwdDetLayer=im->layer();
946  //
947  // keep remaining (valid) hits for verification
948  //
949  else if ( hit->isValid() ) {
950  //std::cout << "Adding a remaining hit" << std::endl;
951  remainingHits.push_back(hit);
952  }
953  }
954  //
955  // Fit only if required number of valid hits can be used
956  //
957  if ( nHit<nHitMin ){ //|| nHit2d<theMinNrOf2dHitsForRebuild ) {
958  fittedTracks.clear();
959  return;
960  }
961  //
962  // Do the backward fit (important: start from scaled, not random cov. matrix!)
963  //
965  //cout << "firstTsos "<< firstTsos << endl;
966  firstTsos.rescaleError(10.);
967  //TrajectoryContainer bwdFitted(fitter.fit(fwdTraj.seed(),fwdTraj.recHits(),firstTsos));
968  TrajectoryContainer bwdFitted(fitter.fit(
970  fwdTraj.recHits(),firstTsos));
971  if (bwdFitted.size()){
972  LogDebug("CkfPattern")<<"Obtained " << bwdFitted.size() << " bwdFitted trajectories with measurement size " << bwdFitted.front().measurements().size();
973  TempTrajectory fitted(fwdTraj.seed(), fwdTraj.direction());
974  fitted.setNLoops(fwdTraj.nLoops());
975  vector<TM> tmsbf = bwdFitted.front().measurements();
976  int iDetLayer=0;
977  //this is ugly but the TM in the fitted track do not contain the DetLayer.
978  //So we have to cache the detLayer pointers and replug them in.
979  //For the backward building it would be enaugh to cache the last DetLayer,
980  //but for the intermediary cleaning we need all
981  for ( vector<TM>::const_iterator im=tmsbf.begin();im!=tmsbf.end(); im++ ) {
982  fitted.push(TM( (*im).forwardPredictedState(),
983  (*im).backwardPredictedState(),
984  (*im).updatedState(),
985  (*im).recHit(),
986  (*im).estimate(),
987  bwdDetLayer[iDetLayer]));
988 
989  LogDebug("CkfPattern")<<PrintoutHelper::dumpMeasurement(*im);
990  iDetLayer++;
991  }
992 /*
993  TM lastMeas = bwdFitted.front().lastMeasurement();
994  fitted.pop();
995  fitted.push(TM(lastMeas.forwardPredictedState(),
996  lastMeas.backwardPredictedState(),
997  lastMeas.updatedState(),
998  lastMeas.recHit(),
999  lastMeas.estimate(),
1000  lastBwdDetLayer));*/
1001  fittedTracks.push_back(fitted);
1002  }
1003  //
1004  // save result
1005  //
1006  //fittedTracks.swap(bwdFitted);
1007  //cout << "Obtained " << fittedTracks.size() << " fittedTracks trajectories with measurement size " << fittedTracks.front().measurements().size() << endl;
1008 }
1009 
1010 bool
1012  size_t maxDepth,
1013  const std::vector<const TrackingRecHit*>& hits) const
1014 {
1015  //
1016  // verify presence of the seeding hits
1017  //
1018  LogDebug("CkfPattern")<<"Checking for " << hits.size() << " hits in "
1019  << maxDepth << " measurements" << endl;
1020 
1022  while (maxDepth > 0) { --maxDepth; --rend; }
1023  for ( vector<const TrackingRecHit*>::const_iterator ir=hits.begin();
1024  ir!=hits.end(); ir++ ) {
1025  // assume that all seeding hits are valid!
1026  bool foundHit(false);
1027  for ( TempTrajectory::DataContainer::const_iterator im=rbegin; im!=rend; --im ) {
1028  if ( im->recHit()->isValid() && (*ir)->sharesInput(im->recHit()->hit(), TrackingRecHit::some) ) {
1029  foundHit = true;
1030  break;
1031  }
1032  }
1033  if ( !foundHit ) return false;
1034  }
1035  return true;
1036 }
1037 
1038 
1039 
1040 
#define LogDebug(id)
T getParameter(std::string const &) const
const TrajectorySeed & seed() const
Access to the seed used to reconstruct the Trajectory.
const_iterator rend() const
Definition: bqueue.h:145
int i
Definition: DBlmapReader.cc:9
static std::string dumpCandidates(collection &candidates)
void groupedIntermediaryClean(TempTrajectoryContainer &theTrajectories) const dso_internal
intermediate cleaning in the case of grouped measurements
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:187
virtual float length() const =0
T perp() const
Definition: PV3DBase.h:71
virtual PropagationDirection propagationDirection() const
Definition: Propagator.h:143
const Propagator * theBackwardPropagator
void layers(const TempTrajectory::DataContainer &measurements, std::vector< const DetLayer * > &fillme) const dso_internal
TrajectorySeed const & seed() const
Access to the seed used to reconstruct the Trajectory.
Definition: Trajectory.h:265
bool empty() const
Definition: bqueue.h:147
virtual Location location() const =0
Which part of the detector (barrel, endcap)
static void clean(TempTrajectoryContainer &tracks)
TrajectoryContainer trajectories(const TrajectorySeed &) const
set Event for the internal MeasurementTracker data member
const CurvilinearTrajectoryError & curvilinearError() const
void addToResult(TempTrajectory &traj, TrajectoryContainer &result, bool inOut=false) const
bool advanceOneLayer(TempTrajectory &traj, const TrajectoryFilter *regionalCondition, const Propagator *propagator, bool inOut, TempTrajectoryContainer &newCand, TempTrajectoryContainer &result) const dso_internal
const DataContainer & measurements() const
GroupedCkfTrajectoryBuilder(const edm::ParameterSet &conf, const TrajectoryStateUpdator *updator, const Propagator *propagatorAlong, const Propagator *propagatorOpposite, const Chi2MeasurementEstimatorBase *estimator, const TransientTrackingRecHitBuilder *RecHitBuilder, const MeasurementTracker *measurementTracker, const TrajectoryFilter *filter, const TrajectoryFilter *inOutFilter)
constructor from ParameterSet
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
void setNLoops(signed char value)
Definition: Trajectory.h:321
T y() const
Definition: PV3DBase.h:62
void setNLoops(signed char value)
const TrajectoryStateUpdator * theUpdator
virtual void analyseSeed(const TrajectorySeed &seed) const
GlobalPoint globalPosition() const
ConstRecHitPointer recHit() const
int foundHits() const
obsolete name, use measurements() instead.
TempTrajectoryContainer segments(const TSOS startingState)
new segments within layer
bool tkxor(bool a, bool b) const dso_internal
std::string whatIsTheNextStep(TempTrajectory &traj, std::pair< TrajectoryStateOnSurface, std::vector< const DetLayer * > > &stateAndLayers)
static std::string dumpMeasurement(const TrajectoryMeasurement &tm)
static std::string dumpMeasurements(const std::vector< TrajectoryMeasurement > &v)
bool verifyHits(TempTrajectory::DataContainer::const_iterator rbegin, size_t maxDepth, const std::vector< const TrackingRecHit * > &hits) const dso_internal
Verifies presence of a RecHits in a range of TrajectoryMeasurements.
signed char nLoops() const
Definition: Trajectory.h:319
ConstRecHitContainer recHits(bool splitting=false) const
Definition: Trajectory.cc:67
PropagationDirection const & direction() const
Definition: Trajectory.cc:195
const LayerMeasurements * theLayerMeasurements
PropagationDirection direction() const
void setDPhiCacheForLoopersReconstruction(float dphi)
virtual void analyseResult(const TrajectoryContainer &result) const
Scalar radius() const
Radius of the cylinder.
Definition: Cylinder.h:55
const T & max(const T &a, const T &b)
PropagationDirection oppositeDirection(PropagationDirection dir) const dso_internal
change of propagation direction
T sqrt(T t)
Definition: SSEVec.h:46
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
virtual const BoundDisk & specificSurface() const
const Chi2MeasurementEstimatorBase & estimator() const
std::string whatIsTheStateToUse(TrajectoryStateOnSurface &initial, TrajectoryStateOnSurface &stateToUse, const DetLayer *l)
std::pair< const_iterator, const_iterator > range
void rebuildSeedingRegion(const TrajectorySeed &, TrajectoryContainer &result) const
const DetLayer * layer() const
TrajectoryStateOnSurface updatedState() const
void backwardFit(TempTrajectory &candidate, unsigned int nSeed, const TrajectoryFitter &fitter, TempTrajectoryContainer &fittedTracks, std::vector< const TrackingRecHit * > &remainingHits) const dso_internal
tuple conf
Definition: dbtoconf.py:185
bool isValid() const
const Bounds & bounds() const
Definition: BoundSurface.h:89
const MeasurementTracker * theMeasurementTracker
TrajectoryMeasurement const & firstMeasurement() const
Definition: Trajectory.h:194
std::vector< TempTrajectory > TempTrajectoryContainer
iterator rbegin()
Definition: bqueue.h:143
range recHits() const
bool isValid() const
virtual const BoundCylinder & specificSurface() const
Extension of the interface.
void buildTrajectories(const TrajectorySeed &, TrajectoryContainer &ret, const TrajectoryFilter *) const dso_internal
common part of both public trajectory building methods
const TrajectoryStateUpdator & updator() const
TrajectoryStateOnSurface extrapolate(const FreeTrajectoryState &fts, const GlobalPoint &vtx) const
extrapolation with default (=geometrical) propagator
virtual std::vector< Trajectory > fit(const Trajectory &) const =0
const AlgebraicSymMatrix55 & matrix() const
GlobalVector globalMomentum() const
bool toBeContinued(TempTrajectory &traj, bool inOut=false) const
StateAndLayers findStateAndLayers(const TempTrajectory &traj) const
tuple cout
Definition: gather_cfg.py:121
size_type size() const
Definition: bqueue.h:146
Definition: Bounds.h:18
signed char nLoops() const
const DetLayer * lastLayer() const
Redundant method, returns the layer of lastMeasurement() .
T x() const
Definition: PV3DBase.h:61
const PositionType & position() const
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:35
Definition: Phi.h:20
std::vector< Trajectory > TrajectoryContainer
const Chi2MeasurementEstimatorBase * theEstimator
TempTrajectory createStartingTrajectory(const TrajectorySeed &seed) const
void push(const TrajectoryMeasurement &tm)
void groupedLimitedCandidates(TempTrajectory &startingTraj, const TrajectoryFilter *regionalCondition, const Propagator *propagator, bool inOut, TempTrajectoryContainer &result) const dso_internal
const Propagator * theForwardPropagator