test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CkfTrajectoryBuilder.cc
Go to the documentation of this file.
2 
4 
6 
10 
17 
18 
21 
23 
27 
28 using namespace std;
29 
32  BaseCkfTrajectoryBuilder::createTrajectoryFilter(conf.getParameter<edm::ParameterSet>("trajectoryFilter"), iC))
33 {}
34 
36  BaseCkfTrajectoryBuilder(conf, filter)
37 {
38  theMaxCand = conf.getParameter<int>("maxCand");
39  theLostHitPenalty = conf.getParameter<double>("lostHitPenalty");
40  theIntermediateCleaning = conf.getParameter<bool>("intermediateCleaning");
41  theAlwaysUseInvalidHits = conf.getParameter<bool>("alwaysUseInvalidHits");
42  /*
43  theSharedSeedCheck = conf.getParameter<bool>("SharedSeedCheck");
44  std::stringstream ss;
45  ss<<"CkfTrajectoryBuilder_"<<conf.getParameter<std::string>("ComponentName")<<"_"<<this;
46  theUniqueName = ss.str();
47  LogDebug("CkfPattern")<<"my unique name is: "<<theUniqueName;
48  */
49 }
50 
51 /*
52  void CkfTrajectoryBuilder::setEvent(const edm::Event& event) const
53  {
54  theMeasurementTracker->update(event);
55  }
56 */
57 
59 }
60 
63 {
65  result.reserve(5);
66  trajectories(seed, result);
67  return result;
68 }
69 
70 /*
71  void CkfTrajectoryBuilder::rememberSeedAndTrajectories(const TrajectorySeed& seed,
72  CkfTrajectoryBuilder::TrajectoryContainer &result) const
73  {
74 
75  //result ----> theCachedTrajectories
76  //every first iteration on event. forget about everything that happened before
77  if (edm::Service<UpdaterService>()->checkOnce(theUniqueName))
78  theCachedTrajectories.clear();
79 
80  if (seed.nHits()==0) return;
81 
82  //then remember those trajectories
83  for (TrajectoryContainer::iterator traj=result.begin();
84  traj!=result.end(); ++traj) {
85  theCachedTrajectories.insert(std::make_pair(seed.recHits().first->geographicalId(),*traj));
86  }
87  }
88 
89  bool CkfTrajectoryBuilder::sharedSeed(const TrajectorySeed& s1,const TrajectorySeed& s2) const{
90  //quit right away on nH=0
91  if (s1.nHits()==0 || s2.nHits()==0) return false;
92  //quit right away if not the same number of hits
93  if (s1.nHits()!=s2.nHits()) return false;
94  TrajectorySeed::range r1=s1.recHits();
95  TrajectorySeed::range r2=s2.recHits();
96  TrajectorySeed::const_iterator i1,i2;
97  TrajectorySeed::const_iterator & i1_e=r1.second,&i2_e=r2.second;
98  TrajectorySeed::const_iterator & i1_b=r1.first,&i2_b=r2.first;
99  //quit right away if first detId does not match. front exist because of ==0 ->quit test
100  if(i1_b->geographicalId() != i2_b->geographicalId()) return false;
101  //then check hit by hit if they are the same
102  for (i1=i1_b,i2=i2_b;i1!=i1_e,i2!=i2_e;++i1,++i2){
103  if (!i1->sharesInput(&(*i2),TrackingRecHit::all)) return false;
104  }
105  return true;
106  }
107  bool CkfTrajectoryBuilder::seedAlreadyUsed(const TrajectorySeed& seed,
108  CkfTrajectoryBuilder::TempTrajectoryContainer &candidates) const
109  {
110  //theCachedTrajectories ---> candidates
111  if (seed.nHits()==0) return false;
112  bool answer=false;
113  pair<SharedTrajectory::const_iterator, SharedTrajectory::const_iterator> range =
114  theCachedTrajectories.equal_range(seed.recHits().first->geographicalId());
115  SharedTrajectory::const_iterator trajP;
116  for (trajP = range.first; trajP!=range.second;++trajP){
117  //check whether seeds are identical
118  if (sharedSeed(trajP->second.seed(),seed)){
119  candidates.push_back(trajP->second);
120  answer=true;
121  }//already existing trajectory shares the seed.
122  }//loop already made trajectories
123 
124  return answer;
125  }
126 */
127 
128 void
130 {
131  // analyseSeed( seed);
132  /*
133  if (theSharedSeedCheck){
134  TempTrajectoryContainer candidates;
135  if (seedAlreadyUsed(seed,candidates))
136  {
137  //start with those candidates already made before
138  limitedCandidates(candidates,result);
139  //and quit
140  return;
141  }
142  }
143  */
144 
145  buildTrajectories(seed, result,nullptr);
146 }
147 
150  const TrajectoryFilter*) const {
151  if (theMeasurementTracker == 0) {
152  throw cms::Exception("LogicError") << "Asking to create trajectories to an un-initialized CkfTrajectoryBuilder.\nYou have to call clone(const MeasurementTrackerEvent *data) and then call trajectories on it instead.\n";
153  }
154 
155  TempTrajectory && startingTraj = createStartingTrajectory( seed );
156 
159  limitedCandidates(seed, startingTraj, result);
160 
161  return startingTraj;
162 
163  /*
164  //and remember what you just did
165  if (theSharedSeedCheck) rememberSeedAndTrajectories(seed,result);
166  */
167 
168  // analyseResult(result);
169 }
170 
174 {
176  candidates.push_back( startingTraj);
177  boost::shared_ptr<const TrajectorySeed> sharedSeed(new TrajectorySeed(seed));
178  limitedCandidates(sharedSeed, candidates,result);
179 }
180 
182 limitedCandidates(const boost::shared_ptr<const TrajectorySeed> & sharedSeed, TempTrajectoryContainer &candidates,
184 {
185  unsigned int nIter=1;
186  TempTrajectoryContainer newCand; // = TrajectoryContainer();
187  newCand.reserve(2*theMaxCand);
188 
189 
190  auto trajCandLess = [&](TempTrajectory const & a, TempTrajectory const & b) {
191  return (a.chiSquared() + a.lostHits()*theLostHitPenalty) <
192  (b.chiSquared() + b.lostHits()*theLostHitPenalty);
193  };
194 
195 
196  while ( !candidates.empty()) {
197 
198  newCand.clear();
199  for (auto traj=candidates.begin(); traj!=candidates.end(); traj++) {
200  std::vector<TM> meas;
201  findCompatibleMeasurements(*sharedSeed, *traj, meas);
202 
203  // --- method for debugging
204  if(!analyzeMeasurementsDebugger(*traj,meas,
206  forwardPropagator(*sharedSeed),theEstimator,
207  theTTRHBuilder)) return;
208  // ---
209 
210  if ( meas.empty()) {
211  addToResult(sharedSeed, *traj, result);
212  }
213  else {
214  std::vector<TM>::const_iterator last;
215  if ( theAlwaysUseInvalidHits) last = meas.end();
216  else {
217  if (meas.front().recHit()->isValid()) {
218  last = find_if( meas.begin(), meas.end(), RecHitIsInvalid());
219  }
220  else last = meas.end();
221  }
222 
223  for(auto itm = meas.begin(); itm != last; itm++) {
224  TempTrajectory newTraj = *traj;
225  updateTrajectory( newTraj, std::move(*itm));
226 
227  if ( toBeContinued(newTraj)) {
228  newCand.push_back(std::move(newTraj)); std::push_heap(newCand.begin(),newCand.end(),trajCandLess);
229  }
230  else {
231  addToResult(sharedSeed, newTraj, result);
233  }
234  }
235  }
236 
237 
238  /*
239  auto trajVal = [&](TempTrajectory const & a) {
240  return a.chiSquared() + a.lostHits()*theLostHitPenalty;
241  };
242 
243  // safe (stable?) logig: always sort, kill exceeding only if worse than last to keep
244  // if ((int)newCand.size() > theMaxCand) std::cout << "TrajVal " << theMaxCand << ' ' << newCand.size() << ' ' << trajVal(newCand.front());
245  int toCut = int(newCand.size()) - int(theMaxCand);
246  if (toCut>0) {
247  // move largest "toCut" to the end
248  for (int i=0; i<toCut; ++i)
249  std::pop_heap(newCand.begin(),newCand.end()-i,trajCandLess);
250  auto fval = trajVal(newCand.front());
251  // remove till equal to highest to keep
252  for (int i=0; i<toCut; ++i) {
253  if (fval==trajVal(newCand.back())) break;
254  newCand.pop_back();
255  }
256  //assert((int)newCand.size() >= theMaxCand);
257  //std::cout << "; " << newCand.size() << ' ' << trajVal(newCand.front()) << " " << trajVal(newCand.back());
258 
259  // std::make_heap(newCand.begin(),newCand.end(),trajCandLess);
260  // push_heap again the one left
261  for (auto iter = newCand.begin()+theMaxCand+1; iter<=newCand.end(); ++iter )
262  std::push_heap(newCand.begin(),iter,trajCandLess);
263 
264  // std::cout << "; " << newCand.size() << ' ' << trajVal(newCand.front()) << " " << trajVal(newCand.back()) << std::endl;
265  }
266 
267  */
268 
269 
270  // intermedeate login: always sort, kill all exceeding
271  while ((int)newCand.size() > theMaxCand) {
272  std::pop_heap(newCand.begin(),newCand.end(),trajCandLess);
273  // if ((int)newCand.size() == theMaxCand+1) std::cout << " " << trajVal(newCand.front()) << " " << trajVal(newCand.back()) << std::endl;
274  newCand.pop_back();
275  }
276 
277  /*
278  // original logic: sort only if > theMaxCand, kill all exceeding
279  if ((int)newCand.size() > theMaxCand) {
280  std::sort( newCand.begin(), newCand.end(), TrajCandLess<TempTrajectory>(theLostHitPenalty));
281  // std::partial_sort( newCand.begin(), newCand.begin()+theMaxCand, newCand.end(), TrajCandLess<TempTrajectory>(theLostHitPenalty));
282  std::cout << "TrajVal " << theMaxCand << ' ' << newCand.size() << ' '
283  << trajVal(newCand.back()) << ' ' << trajVal(newCand[theMaxCand-1]) << ' ' << trajVal(newCand[theMaxCand]) << std::endl;
284  newCand.resize(theMaxCand);
285  }
286  */
287 
288  } // end loop on candidates
289 
290  std::sort_heap(newCand.begin(),newCand.end(),trajCandLess);
292 
293  candidates.swap(newCand);
294 
295  LogDebug("CkfPattern") <<result.size()<<" candidates after "<<nIter++<<" CKF iteration: \n"
297  <<"\n "<<candidates.size()<<" running candidates are: \n"
298  <<PrintoutHelper::dumpCandidates(candidates);
299 
300  }
301 }
302 
303 
304 
306  TM && tm) const
307 {
308  auto && predictedState = tm.predictedState();
309  auto && hit = tm.recHit();
310  if ( hit->isValid()) {
311  auto && upState = theUpdator->update( predictedState, *hit);
312  traj.emplace( std::move(predictedState), std::move(upState),
313  std::move(hit), tm.estimate(), tm.layer());
314  }
315  else {
316  traj.emplace( std::move(predictedState), std::move(hit), 0, tm.layer());
317  }
318 }
319 
320 
321 void
323  const TempTrajectory& traj,
324  std::vector<TrajectoryMeasurement> & result) const
325 {
326  int invalidHits = 0;
327  //Use findStateAndLayers which handles the hitless seed use case
328  std::pair<TSOS,std::vector<const DetLayer*> > && stateAndLayers = findStateAndLayers(seed,traj);
329  if (stateAndLayers.second.empty()) return;
330 
331  auto layerBegin = stateAndLayers.second.begin();
332  auto layerEnd = stateAndLayers.second.end();
333  LogDebug("CkfPattern")<<"looping on "<< stateAndLayers.second.size()<<" layers.";
334  const Propagator *fwdPropagator = forwardPropagator(seed);
335  for (auto il = layerBegin; il != layerEnd; il++) {
336 
337  LogDebug("CkfPattern")<<"looping on a layer in findCompatibleMeasurements.\n last layer: "<<traj.lastLayer()<<" current layer: "<<(*il);
338 
339  TSOS stateToUse = stateAndLayers.first;
340  //Added protection before asking for the lastLayer on the trajectory
341  if unlikely (!traj.empty() && (*il)==traj.lastLayer()) {
342  LogDebug("CkfPattern")<<" self propagating in findCompatibleMeasurements.\n from: \n"<<stateToUse;
343  //self navigation case
344  // go to a middle point first
346  GlobalPoint center(0,0,0);
347  stateToUse = middle.extrapolate(stateToUse, center, *fwdPropagator);
348 
349  if (!stateToUse.isValid()) continue;
350  LogDebug("CkfPattern")<<"to: "<<stateToUse;
351  }
352 
353  LayerMeasurements layerMeasurements(theMeasurementTracker->measurementTracker(), *theMeasurementTracker);
354  std::vector<TrajectoryMeasurement> && tmp = layerMeasurements.measurements((**il),stateToUse, *fwdPropagator, *theEstimator);
355 
356  if ( !tmp.empty()) {
357  if ( result.empty()) result.swap(tmp);
358  else {
359  // keep one dummy TM at the end, skip the others
360  result.insert( result.end()-invalidHits,
361  std::make_move_iterator(tmp.begin()), std::make_move_iterator(tmp.end()));
362  }
363  invalidHits++;
364  }
365  }
366 
367  // sort the final result, keep dummy measurements at the end
368  if ( result.size() > 1) {
369  std::sort( result.begin(), result.end()-invalidHits, TrajMeasLessEstim());
370  }
371 
372  LogDebug("CkfPattern")<<"starting from:\n"
373  <<"x: "<<stateAndLayers.first.globalPosition()<<"\n"
374  <<"p: "<<stateAndLayers.first.globalMomentum()<<"\n"
376 
377 #ifdef DEBUG_INVALID
378  bool afterInvalid = false;
379  for (vector<TM>::const_iterator i=result.begin();
380  i!=result.end(); i++) {
381  if ( ! i->recHit().isValid()) afterInvalid = true;
382  if (afterInvalid && i->recHit().isValid()) {
383  edm::LogError("CkfPattern") << "CkfTrajectoryBuilder error: valid hit after invalid!" ;
384  }
385  }
386 #endif
387 
388  //analyseMeasurements( result, traj);
389 
390 }
391 
#define LogDebug(id)
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
static std::string dumpCandidates(collection &candidates)
std::vector< Trajectory > TrajectoryContainer
bool empty() const
True if trajectory has no measurements.
static void clean(TempTrajectoryContainer &tracks)
const Propagator * forwardPropagator(const TrajectorySeed &seed) const
CkfTrajectoryBuilder(const edm::ParameterSet &conf, edm::ConsumesCollector &iC)
virtual bool analyzeMeasurementsDebugger(Trajectory &traj, const std::vector< TrajectoryMeasurement > &meas, const MeasurementTrackerEvent *theMeasurementTracker, const Propagator *theForwardPropagator, const Chi2MeasurementEstimatorBase *theEstimator, const TransientTrackingRecHitBuilder *theTTRHBuilder) const
const TrajectoryStateUpdator * theUpdator
TempTrajectory buildTrajectories(const TrajectorySeed &, TrajectoryContainer &ret, const TrajectoryFilter *) const
static std::string dumpMeasurements(const std::vector< TrajectoryMeasurement > &v)
tuple result
Definition: mps_fire.py:83
#define unlikely(x)
virtual TrajectoryStateOnSurface update(const TrajectoryStateOnSurface &, const TrackingRecHit &) const =0
const TransientTrackingRecHitBuilder * theTTRHBuilder
def move
Definition: eostools.py:510
void addToResult(boost::shared_ptr< const TrajectorySeed > const &seed, TempTrajectory &traj, TrajectoryContainer &result, bool inOut=false) const
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
StateAndLayers findStateAndLayers(const TrajectorySeed &seed, const TempTrajectory &traj) const
const MeasurementTrackerEvent * theMeasurementTracker
virtual TrajectoryContainer trajectories(const TrajectorySeed &seed) const
trajectories building starting from a seed
std::vector< TempTrajectory > TempTrajectoryContainer
float chiSquared() const
Value of the raw Chi2 of the trajectory, not normalised to the N.D.F.
double b
Definition: hdecay.h:120
TrajectoryStateOnSurface extrapolate(const FreeTrajectoryState &fts, const GlobalPoint &vtx) const
extrapolation with default (=geometrical) propagator
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
void emplace(Args &&...args)
bool toBeContinued(TempTrajectory &traj, bool inOut=false) const
double a
Definition: hdecay.h:121
virtual void findCompatibleMeasurements(const TrajectorySeed &seed, const TempTrajectory &traj, std::vector< TrajectoryMeasurement > &result) const
void updateTrajectory(TempTrajectory &traj, TM &&tm) const
void setEvent_(const edm::Event &iEvent, const edm::EventSetup &iSetup) override
const DetLayer * lastLayer() const
Redundant method, returns the layer of lastMeasurement() .
int theMaxCand
set Event for the internal MeasurementTracker data member
std::vector< Trajectory > TrajectoryContainer
const Chi2MeasurementEstimatorBase * theEstimator
TempTrajectory createStartingTrajectory(const TrajectorySeed &seed) const
int lostHits() const
void limitedCandidates(const TrajectorySeed &seed, TempTrajectory &startingTraj, TrajectoryContainer &result) const