CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TrajectorySegmentBuilder.cc
Go to the documentation of this file.
1 
3 
6 
19 
20 #include <algorithm>
21 
22 // #define DBG_TSB
23 
24 namespace {
25 #ifdef STAT_TSB
26  struct StatCount {
27  long long totGroup;
28  long long totSeg;
29  long long totLockHits;
30  void zero() {
31  totGroup=totSeg=totLockHits=0;
32  }
33  void incr(long long g, long long s, long long l) {
34  totGroup+=g;
35  totSeg+=s;
36  totLockHits+=l;
37  }
38  void print() const {
39  std::cout << "TrajectorySegmentBuilder stat\nGroup/Seg/Lock "
40  << totGroup<<'/'<<totSeg<<'/'<<totLockHits
41  << std::endl;
42  }
43  StatCount() { zero();}
44  ~StatCount() { print();}
45  };
46 
47 #else
48  struct StatCount {
49  void incr(long long, long long, long long){}
50  };
51 #endif
52 
53  StatCount statCount;
54 
55 }
56 
57 
58 using namespace std;
59 
62 {
63  //
64  // create empty trajectory
65  //
66  theLockedHits.clear();
67  TempTrajectory startingTrajectory(theFullPropagator.propagationDirection());
68  //
69  // get measurement groups
70  //
71  vector<TMG> measGroups =
72  theLayerMeasurements->groupedMeasurements(theLayer,startingState,theFullPropagator,theEstimator);
73  //B.M. theLayer.groupedMeasurements(startingState,theFullPropagator,theEstimator);
74 
75 #ifdef DBG_TSB
76  cout << "TSB: number of measurement groups = " << measGroups.size() << endl;
77  // theDbgFlg = measGroups.size()>1;
78  theDbgFlg = true;
79 #else
80  theDbgFlg = false;
81 #endif
82 
83 
84 #ifdef DBG_TSB
85  if ( theDbgFlg ) {
86  int ntot(1);
87  for (vector<TMG>::const_iterator ig=measGroups.begin();
88  ig!=measGroups.end(); ++ig) {
89  int ngrp(0);
90  const vector<TM>& measurements = ig->measurements();
91  for ( vector<TM>::const_iterator im=measurements.begin();
92  im!=measurements.end(); ++im ) {
93  if ( im->recHit()->isValid() ) ngrp++;
94  }
95  cout << " " << ngrp;
96  if ( ngrp>0 ) ntot *= ngrp;
97  }
98  cout << endl;
99  cout << "TrajectorySegmentBuilder::partialTrajectories:: det ids & hit types / group" << endl;
100  for (vector<TMG>::const_iterator ig=measGroups.begin();
101  ig!=measGroups.end(); ++ig) {
102  const vector<TM>& measurements = ig->measurements();
103  for ( vector<TM>::const_iterator im=measurements.begin();
104  im!=measurements.end(); ++im ) {
105  if ( im!=measurements.begin() ) cout << " / ";
106  if ( im->recHit()->det() )
107  cout << im->recHit()->det()->geographicalId().rawId() << " "
108  << im->recHit()->getType();
109  else
110  cout << "no det";
111  }
112  cout << endl;
113  }
114 
115 
116 // if ( measGroups.size()>4 ) {
117  cout << typeid(theLayer).name() << endl;
118  cout << startingState.localError().matrix() << endl;
119 // for (vector<TMG>::const_iterator ig=measGroups.begin();
120 // ig!=measGroups.end(); ig++) {
121 // cout << "Nr. of measurements = " << ig->measurements().size() << endl;
122 // const DetGroup& dg = ig->detGroup();
123 // for ( DetGroup::const_iterator id=dg.begin();
124 // id!=dg.end(); id++ ) {
125 // GlobalPoint p(id->det()->position());
126 // GlobalVector v(id->det()->toGlobal(LocalVector(0.,0.,1.)));
127 // cout << p.perp() << " " << p.phi() << " " << p.z() << " ; "
128 // << v.phi() << " " << v.z() << endl;
129 // }
130 // }
131 // }
132  }
133 #endif
134 
135  TempTrajectoryContainer candidates =
136  addGroup(startingTrajectory,measGroups.begin(),measGroups.end());
137 
138  if (theDbgFlg) cout << "TSB: back with " << candidates.size() << " candidates" << endl;
139  // clean
140  //
141  //
142  // add invalid hit - try to get first detector hit by the extrapolation
143  //
144 
145  updateWithInvalidHit(startingTrajectory,measGroups,candidates);
146 
147  if (theDbgFlg) cout << "TSB: " << candidates.size() << " candidates after invalid hit" << endl;
148 
149  statCount.incr(measGroups.size(), candidates.size(), theLockedHits.size());
150 
151 
152  theLockedHits.clear();
153 
154  return candidates;
155 }
156 
158  const TM& tm) const
159 {
160  TSOS predictedState = tm.predictedState();
162 
163  if ( hit->isValid()) {
164  traj.push( TM( predictedState, theUpdator.update( predictedState, *hit),
165  hit, tm.estimate(), tm.layer()));
166 
167 // TrajectoryMeasurement tm(traj.lastMeasurement());
168 // if ( tm.updatedState().isValid() ) {
169 // if ( !hit.det().surface().bounds().inside(tm.updatedState().localPosition(),
170 // tm.updatedState().localError().positionError(),3.) ) {
171 // cout << "Incompatibility after update for det at " << hit.det().position() << ":" << endl;
172 // cout << tm.predictedState().localPosition() << " "
173 // << tm.predictedState().localError().positionError() << endl;
174 // cout << hit.localPosition() << " " << hit.localPositionError() << endl;
175 // cout << tm.updatedState().localPosition() << " "
176 // << tm.updatedState().localError().positionError() << endl;
177 // }
178 // }
179  }
180  else {
181  traj.push( TM( predictedState, hit,0, tm.layer()));
182  }
183 }
184 
185 
188  vector<TMG>::const_iterator begin,
189  vector<TMG>::const_iterator end)
190 {
191  vector<TempTrajectory> ret;
192  if ( begin==end ) {
193  //std::cout << "TrajectorySegmentBuilder::addGroup" << " traj.empty()=" << traj.empty() << "EMPTY" << std::endl;
194  if (theDbgFlg) cout << "TSB::addGroup : no groups left" << endl;
195  if ( !traj.empty() )
196  ret.push_back(traj);
197  return ret;
198  }
199 
200  if (theDbgFlg) cout << "TSB::addGroup : traj.size() = " << traj.measurements().size()
201  << " first group at " << &(*begin)
202  // << " nr. of candidates = " << candidates.size()
203  << endl;
204 
205 
206  TempTrajectoryContainer updatedTrajectories; updatedTrajectories.reserve(2);
207  if ( traj.measurements().empty() ) {
208  vector<TM> firstMeasurements = unlockedMeasurements(begin->measurements());
209  if ( theBestHitOnly )
210  updateCandidatesWithBestHit(traj,firstMeasurements,updatedTrajectories);
211  else
212  updateCandidates(traj,begin->measurements(),updatedTrajectories);
213  if (theDbgFlg) cout << "TSB::addGroup : updating with first group - "
214  << updatedTrajectories.size() << " trajectories" << endl;
215  }
216  else {
217  if ( theBestHitOnly )
218  updateCandidatesWithBestHit(traj,redoMeasurements(traj,begin->detGroup()),
219  updatedTrajectories);
220  else
221  updateCandidates(traj,redoMeasurements(traj,begin->detGroup()),
222  updatedTrajectories);
223  if (theDbgFlg) cout << "TSB::addGroup : updating"
224  << updatedTrajectories.size() << " trajectories" << endl;
225  }
226 
227  if (begin+1 != end) {
228  ret.reserve(4); // a good upper bound
229  for ( TempTrajectoryContainer::iterator it=updatedTrajectories.begin();
230  it!=updatedTrajectories.end(); ++it ) {
231  if (theDbgFlg) cout << "TSB::addGroup : trying to extend candidate at "
232  << &(*it) << " size " << it->measurements().size() << endl;
233  vector<TempTrajectory> finalTrajectories = addGroup(*it,begin+1,end);
234  if (theDbgFlg) cout << "TSB::addGroup : " << finalTrajectories.size()
235  << " finalised candidates before cleaning" << endl;
236  //B.M. to be ported later
237  cleanCandidates(finalTrajectories);
238 
239  if (theDbgFlg) cout << "TSB::addGroup : got " << finalTrajectories.size()
240  << " finalised candidates" << endl;
241  ret.insert(ret.end(),finalTrajectories.begin(),
242  finalTrajectories.end());
243  }
244  } else {
245  ret.reserve(updatedTrajectories.size());
246  for (TempTrajectoryContainer::iterator it=updatedTrajectories.begin();
247  it!=updatedTrajectories.end(); ++it ) {
248  if (!it->empty()) ret.push_back(*it);
249  }
250  }
251 
252  //std::cout << "TrajectorySegmentBuilder::addGroup" <<
253  // " traj.empty()=" << traj.empty() <<
254  // " end-begin=" << (end-begin) <<
255  // " #updated=" << updatedTrajectories.size() <<
256  // " #result=" << ret.size() << std::endl;
257  return ret;
258 }
259 
260 void
262  const vector<TM>& measurements,
263  TempTrajectoryContainer& candidates)
264 {
265  //
266  // generate updated candidates with all valid hits
267  //
268  for ( vector<TM>::const_iterator im=measurements.begin();
269  im!=measurements.end(); ++im ) {
270  if ( im->recHit()->isValid() ) {
271  candidates.push_back(traj);
272  updateTrajectory(candidates.back(),*im);
273  if ( theLockHits ) lockMeasurement(*im);
274  }
275  }
276  //
277  // keep old trajectory
278  //
279  candidates.push_back(traj);
280 }
281 
282 void
284  const vector<TM>& measurements,
285  TempTrajectoryContainer& candidates)
286 {
287  vector<TM>::const_iterator ibest = measurements.begin();
288  // get first
289  while(ibest!=measurements.end() && !ibest->recHit()->isValid()) ++ibest;
290  if ( ibest!=measurements.end() ) {
291  // find real best;
292  for ( vector<TM>::const_iterator im=ibest+1;
293  im!=measurements.end(); ++im ) {
294  if ( im->recHit()->isValid() &&
295  im->estimate()<ibest->estimate()
296  )
297  ibest = im;
298  }
299 
300 
301  if ( theLockHits ) lockMeasurement(*ibest);
302  candidates.push_back(traj);
303  updateTrajectory(candidates.back(),*ibest);
304 
305  if ( theDbgFlg )
306  cout << "TSB: found best measurement at "
307  << ibest->recHit()->globalPosition().perp() << " "
308  << ibest->recHit()->globalPosition().phi() << " "
309  << ibest->recHit()->globalPosition().z() << endl;
310 
311  }
312 
313  //
314  // keep old trajectorTempy
315  //
316  candidates.push_back(traj);
317 }
318 
319 vector<TrajectoryMeasurement>
321  const DetGroup& detGroup) const
322 {
323  vector<TM> result;
324  //
325  // loop over all dets
326  //
327  if (theDbgFlg) cout << "TSB::redoMeasurements : nr. of measurements / group =";
328 
329  for (DetGroup::const_iterator idet=detGroup.begin();
330  idet!=detGroup.end(); ++idet) {
331  //
332  // ======== ask for measurements ==============
333  //B.M vector<TM> tmp = idet->det()->measurements(traj.lastMeasurement().updatedState(),
334  // theGeomPropagator,theEstimator);
335 
336  pair<bool, TrajectoryStateOnSurface> compat =
338  traj.lastMeasurement().updatedState(),
339  theGeomPropagator,theEstimator);
340 
341  if (theDbgFlg && !compat.first) cout << " 0";
342 
343  if(!compat.first) continue;
344  const MeasurementDet* mdet = theMeasurementTracker->idToDet(idet->det()->geographicalId());
345  vector<TM> tmp
346  = mdet->fastMeasurements( compat.second, idet->trajectoryState(), theGeomPropagator, theEstimator);
347 
348 
349  //perhaps could be enough just:
350  //vector<TM> tmp = mdet->fastMeasurements( idet->trajectoryState(),
351  // traj.lastMeasurement().updatedState(),
352  // theGeomPropagator, theEstimator);
353  // ==================================================
354 
355  //
356  // only collect valid RecHits
357  //
358  if (theDbgFlg) cout << " " << tmp.size();
359 
360  for(vector<TM>::iterator tmpIt=tmp.begin(); tmpIt!=tmp.end(); ++tmpIt){
361  if ( tmpIt->recHit()->isValid() ) {
362  tmpIt->setLayer(&theLayer); // set layer in TM, because the Det cannot do it
363  result.push_back(*tmpIt);
364  }
365  }
366  }
367  if (theDbgFlg) cout << endl;
368 
369  return result;
370 }
371 
372 void
374  const vector<TMG>& groups,
375  TempTrajectoryContainer& candidates) const
376 {
377  //
378  // first try to find an inactive hit with dets crossed by the prediction,
379  // then take any inactive hit
380  //
381  // loop over groups
382  for ( int iteration=0; iteration<2; iteration++ ) {
383  for ( vector<TMG>::const_iterator ig=groups.begin(); ig!=groups.end(); ++ig) {
384  // loop over measurements
385  const vector<TM>& measurements = ig->measurements();
386  for ( vector<TM>::const_reverse_iterator im=measurements.rbegin();
387  im!=measurements.rend(); ++im ) {
388  ConstRecHitPointer hit = im->recHit();
389  if ( hit->getType()==TrackingRecHit::valid ||
390  hit->getType()==TrackingRecHit::missing ) continue;
391  //
392  // check, if the extrapolation traverses the Det or
393  // if 2nd iteration
394  //
395  if ( hit->det() ) {
396  TSOS predState(im->predictedState());
397  if ( iteration>0 ||
398  (predState.isValid() &&
399  hit->det()->surface().bounds().inside(predState.localPosition())) ) {
400  // add the hit
401  /*TempTrajectory newTraj(traj);
402  updateTrajectory(newTraj,*im);
403  candidates.push_back(newTraj); // FIXME: avoid useless copy */
404  candidates.push_back(traj);
405  updateTrajectory(candidates.back(), *im);
406  if ( theDbgFlg ) cout << "TrajectorySegmentBuilder::updateWithInvalidHit "
407  << "added inactive hit" << endl;
408  return;
409  }
410  }
411  }
412  }
413  }
414  //
415  // No suitable inactive hit: add a missing one
416  //
417  bool found(false);
418  for ( int iteration=0; iteration<2; iteration++ ) {
419  //
420  // loop over groups
421  //
422  for ( vector<TMG>::const_iterator ig=groups.begin();
423  ig!=groups.end(); ++ig) {
424  const vector<TM>& measurements = ig->measurements();
425  for ( vector<TM>::const_reverse_iterator im=measurements.rbegin();
426  im!=measurements.rend(); ++im ) {
427  //
428  // only use invalid hits
429  //
430  ConstRecHitPointer hit = im->recHit();
431  if ( hit->isValid() ) continue;
432 
433  //
434  // check, if the extrapolation traverses the Det
435  //
436  TSOS predState(im->predictedState());
437  if(hit->det()){
438  if ( iteration>0 || (predState.isValid() &&
439  hit->det()->surface().bounds().inside(predState.localPosition())) ) {
440  // add invalid hit
441  /*TempTrajectory newTraj(traj);
442  updateTrajectory(newTraj,*im);
443  candidates.push_back(newTraj); // FIXME: avoid useless copy */
444  candidates.push_back(traj);
445  updateTrajectory(candidates.back(), *im);
446  found = true;
447  break;
448  }
449 
450  }else{
451  if ( iteration>0 || (predState.isValid() &&
452  im->layer()->surface().bounds().inside(predState.localPosition())) ){
453  // add invalid hit
454  /*TempTrajectory newTraj(traj);
455  updateTrajectory(newTraj,*im);
456  candidates.push_back(newTraj); // FIXME: avoid useless copy */
457  candidates.push_back(traj);
458  updateTrajectory(candidates.back(), *im);
459  found = true;
460  break;
461  }
462  }
463  }
464  if ( found ) break;
465  }
466  if ( theDbgFlg && !found ) cout << "TrajectorySegmentBuilder::updateWithInvalidHit: "
467  << " did not find invalid hit on 1st iteration" << endl;
468  if ( found ) break;
469  }
470  if ( !found ) {
471  if (theDbgFlg) cout << "TrajectorySegmentBuilder::updateWithInvalidHit: "
472  << " did not find invalid hit" << endl;
473  }
474 }
475 
476 vector<TrajectoryMeasurement>
477 TrajectorySegmentBuilder::unlockedMeasurements (const vector<TM>& measurements) const
478 {
479 // if ( !theLockHits ) return measurements;
480 
481  //========== B.M. to be ported later ===============
482  vector<TM> result;
483  result.reserve(measurements.size());
484 
485  //RecHitEqualByChannels recHitEqual(false,true);
486 
487  for ( vector<TM>::const_iterator im=measurements.begin();
488  im!=measurements.end(); ++im ) {
489  ConstRecHitPointer testHit = im->recHit();
490  if ( !testHit->isValid() ) continue;
491  bool found(false);
492  if ( theLockHits ) {
493  for ( ConstRecHitContainer::const_iterator ih=theLockedHits.begin();
494  ih!=theLockedHits.end(); ++ih ) {
495  if ( (*ih)->hit()->sharesInput(testHit->hit(), TrackingRecHit::all) ) {
496  found = true;
497  break;
498  }
499  }
500  }
501  if ( !found ) result.push_back(*im);
502  }
503  return result;
504  //=================================
505  //return measurements; // temporary solution before RecHitEqualByChannels is ported
506 }
507 
508 void
510 {
511  theLockedHits.push_back(measurement.recHit());
512 }
513 
514 
515 
516 // ================= B.M. to be ported later ===============================
517 void
518 TrajectorySegmentBuilder::cleanCandidates (vector<TempTrajectory>& candidates) const
519 {
520  //
521  // remove candidates which are subsets of others
522  // assumptions: no invalid hits and no duplicates
523  //
524  if ( candidates.size()<=1 ) return;
525  //RecHitEqualByChannels recHitEqual(false,true);
526  //
527  vector<TempTrajectory> sortedCandidates(candidates);
528  sort(sortedCandidates.begin(),sortedCandidates.end(),TrajectoryLessByFoundHits());
529 // cout << "SortedCandidates.foundHits";
530 // for ( vector<Trajectory>::iterator i1=sortedCandidates.begin();
531 // i1!=sortedCandidates.end(); i1++ )
532 // cout << " " << i1->foundHits();
533 // cout << endl;
534  //
535  for ( vector<TempTrajectory>::iterator i1=sortedCandidates.begin();
536  i1!=sortedCandidates.end()-1; ++i1 ) {
537  // get measurements of candidate to be checked
538  const TempTrajectory::DataContainer & measurements1 = i1->measurements();
539  for ( vector<TempTrajectory>::iterator i2=i1+1;
540  i2!=sortedCandidates.end(); ++i2 ) {
541  // no duplicates: two candidates of same size are different
542  if ( i2->foundHits()==i1->foundHits() ) continue;
543  // get measurements of "reference"
544  const TempTrajectory::DataContainer & measurements2 = i2->measurements();
545  //
546  // use the fact that TMs are ordered:
547  // start search in trajectory#1 from last hit match found
548  //
549  bool allFound(true);
550  TempTrajectory::DataContainer::const_iterator from2 = measurements2.rbegin(), im2end = measurements2.rend();
551  for ( TempTrajectory::DataContainer::const_iterator im1=measurements1.rbegin(),im1end = measurements1.rend();
552  im1!=im1end; --im1 ) {
553  // redundant protection - segments should not contain invalid RecHits
554  if ( !im1->recHit()->isValid() ) continue;
555  bool found(false);
557  im2!=im2end; --im2 ) {
558  // redundant protection - segments should not contain invalid RecHits
559  if ( !im2->recHit()->isValid() ) continue;
560  if ( im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::all) ) {
561  found = true;
562  from2 = im2; --from2;
563  break;
564  }
565  }
566  if ( !found ) {
567  allFound = false;
568  break;
569  }
570  }
571  if ( allFound ) i1->invalidate();
572  }
573  }
574 /*
575  candidates.clear();
576  for ( vector<Trajectory>::const_iterator i=sortedCandidates.begin();
577  i!=sortedCandidates.end(); i++ ) {
578  if ( i->isValid() ) candidates.push_back(*i);
579  }
580 */
581  candidates.erase(std::remove_if( candidates.begin(),candidates.end(),
582  std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
583  // boost::bind(&TempTrajectory::isValid,_1)),
584  candidates.end());
585  if (theMaxSegments >=0 && candidates.size() > (unsigned int)theMaxSegments){
586  unsigned int nExtra = candidates.size() - theMaxSegments;
587  //cands are sorted from short to long; long is good
588  candidates.erase(candidates.begin(), candidates.begin()+nExtra);
589  }
590 #ifdef DBG_TSB
591  cout << "TSB: cleanCandidates: reduced from " << sortedCandidates.size()
592  << " to " << candidates.size() << " candidates" << endl;
593 #endif
594  return;
595 }
596 
597 //==================================================
const_iterator rend() const
Definition: bqueue.h:145
void updateCandidatesWithBestHit(TempTrajectory &traj, const std::vector< TM > &measurements, TempTrajectoryContainer &candidates)
creation of a new candidate from a segment and the best hit out of a collection
bool empty() const
True if trajectory has no measurements.
void update(const LocalTrajectoryParameters &p, const Surface &aSurface, const MagneticField *field, const SurfaceSide side=SurfaceSideDefinition::atCenterOfSurface)
bool empty() const
Definition: bqueue.h:147
std::vector< TempTrajectory > TempTrajectoryContainer
void cleanCandidates(std::vector< TempTrajectory > &candidates) const
clean a set of candidates
void updateCandidates(TempTrajectory &traj, const std::vector< TM > &measurements, TempTrajectoryContainer &candidates)
creation of new candidates from a segment and a collection of hits
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
Definition: print.cc:8
const DataContainer & measurements() const
std::vector< TrajectoryMeasurement > unlockedMeasurements(const std::vector< TM > &measurements) const
get list of unused hits
ConstRecHitPointer recHit() const
static std::pair< bool, TrajectoryStateOnSurface > isCompatible(const GeomDet *theDet, const TrajectoryStateOnSurface &ts, const Propagator &prop, const MeasurementEstimator &est)
TempTrajectoryContainer segments(const TSOS startingState)
new segments within layer
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
const TrajectoryMeasurement & lastMeasurement() const
tuple iteration
Definition: align_cfg.py:5
void lockMeasurement(const TM &measurement)
mark a hit as used
tuple result
Definition: query.py:137
std::vector< TrajectoryMeasurement > redoMeasurements(const TempTrajectory &traj, const DetGroup &detGroup) const
retrieve compatible hits from a DetGroup
virtual std::vector< TrajectoryMeasurement > fastMeasurements(const TrajectoryStateOnSurface &stateOnThisDet, const TrajectoryStateOnSurface &startingState, const Propagator &, const MeasurementEstimator &) const =0
const DetLayer * layer() const
TrajectoryStateOnSurface updatedState() const
const AlgebraicSymMatrix55 & matrix() const
#define end
Definition: vmac.h:38
TrajectoryStateOnSurface predictedState() const
const LocalTrajectoryError & localError() const
std::vector< TempTrajectory > addGroup(TempTrajectory &traj, std::vector< TrajectoryMeasurementGroup >::const_iterator begin, std::vector< TrajectoryMeasurementGroup >::const_iterator end)
bool isValid() const
iterator rbegin()
Definition: bqueue.h:143
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
#define begin
Definition: vmac.h:31
tuple cout
Definition: gather_cfg.py:121
size_type size() const
Definition: bqueue.h:146
void updateTrajectory(TempTrajectory &traj, const TM &tm) const
update of a trajectory with a hit
void push(const TrajectoryMeasurement &tm)
void updateWithInvalidHit(TempTrajectory &traj, const std::vector< TMG > &groups, TempTrajectoryContainer &candidates) const