CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonRoadTrajectoryBuilder.cc
Go to the documentation of this file.
2 
13 
21 
22 //#include <DataFormats/GeometrySurface/interface/LocalError.h> //does not exist anymore...
25 
29 
30 //#include <RecoMuon/TrackingTools/interface/VertexRecHit.h>
32 
35 
38 
39 //alternative constructor
41  const MeasurementTracker * mt,
42  const MagneticField * f,
43  const Propagator * p):
44  theRoadEstimator(0),theHitEstimator(0),theUpdator(0),theSmoother(0)
45 {
46 
48  theField = f;
49  thePropagator = p;
50 
51  theCategory = "Muon|RecoMuon|MuonRoadTrajectoryBuilder";
52 
53  //get parameters from ParameterSet
54 
55  //propagator name to get from muon service
56  // thePropagatorName = iConfig.getParameter<std::string>("propagatorName");
57 
58  //chi2 estimator
59  double chi2R=iConfig.getParameter<double>("maxChi2Road");
61  double chi2H=iConfig.getParameter<double>("maxChi2Hit");
62  theHitEstimator = new Chi2MeasurementEstimator(chi2H,sqrt(chi2H));
63 
64  //trajectory updator
65  theUpdator= new KFUpdator();
66 
67  //limit the total number of possible trajectories taken into account for a single seed
68  theMaxTrajectories = iConfig.getParameter<unsigned int>("maxTrajectories");
69 
70  //limit the type of module considered to gather rechits
71  theDynamicMaxNumberOfHitPerModule = iConfig.getParameter<bool>("dynamicMaxNumberOfHitPerModule");
72  theNumberOfHitPerModuleDefault = iConfig.getParameter<unsigned int>("numberOfHitPerModule");
73  theMaxTrajectoriesThreshold = iConfig.getParameter<std::vector<unsigned int> >("maxTrajectoriesThreshold");
74  theNumberOfHitPerModuleThreshold = iConfig.getParameter<std::vector<unsigned int> >("numberOfHitPerModuleThreshold");
75 
76  //could be configurable, but not
80 
81  //output track candidate selection
82  theMinNumberOfHitOnCandidate = iConfig.getParameter<unsigned int>("minNumberOfHitOnCandidate");
83 
84  //single or multiple trajectories per muon
85  theOutputAllTraj = iConfig.getParameter<bool>("outputAllTraj");
86 
87  if (!theSmoother)
89 }
90 
91 //destructor
93 {
94  edm::LogInfo(theCategory)<<"cleaning the object";
96  if (theHitEstimator) delete theHitEstimator;
97  if (theUpdator) delete theUpdator;
98  if (theSmoother) delete theSmoother;
99 }
100 
102  theMeasurementTracker->update(iEvent);
103 }
104 
105 
106 
107 
109 { //order so that first element of the list have
110  //most hits, if equal smallest chi2
111  unsigned int s1=traj1.measurements.size();
112  unsigned int s2=traj2.measurements.size();
113  if (s1>s2) return true; //decreasing order of measurements.size()
114  else {
115  if (s1==s2) return (traj1.chi2<traj2.chi2); //increase order of chi2
116  else return false; }}
117 
118 
120 {
121  LogDebug(theCategory)<<"makeTrajectories START";
122  //process the seed through the tracker
123  makeTrajectories(seed,ret);
124 }
125 
126 //reconstruct trajectory for the trajectory seed
127 std::vector<Trajectory> MuonRoadTrajectoryBuilder::trajectories(const TrajectorySeed & seed) const
128 {
129  LogDebug(theCategory)<<"makeTrajectories START";
130 
131  //default output
132  std::vector<Trajectory> result;
133 
134  //process the seed through the tracker
135  makeTrajectories(seed,result);
136 
137  //output the result of regional tracking
138  return result;
139 }
140 
141 
142 
143 void MuonRoadTrajectoryBuilder::makeTrajectories(const TrajectorySeed & seed, std::vector<Trajectory> & result,int version) const
144 { if (version==0) { makeTrajectories_0(seed,result);}
145  else if (version==1) { makeTrajectories_1(seed,result);}}
146 
147 
148 //home grown tools
149 //old implementation
150 void MuonRoadTrajectoryBuilder::makeTrajectories_0(const TrajectorySeed & seed, std::vector<Trajectory> & result) const
151 {
152  Trajectory basicTrajectory(seed,alongMomentum);
153  //add the muon system measurement to the basicTrajectory
154  //...no yet implemented...
155 
156  //get the initial state
157  PTrajectoryStateOnDet PTstart=seed.startingState();
158  DetId detId(PTstart.detId());
159  const BoundPlane * surface =(&theMeasurementTracker->geomTracker()->idToDet(detId)->surface());
160  //start from this point
162  if (!TSOS.isValid())/*/abort*/{ edm::LogError(theCategory)<<"TSOS from PTSOD is not valid.";return ;}
163 
164  LogDebug(theCategory) <<"(detId.rawId()) "<<(detId.rawId())<<"(detId.subdetId()) "<<(detId.subdetId())
165  <<"(TSOS.globalPosition()) "<<(TSOS.globalPosition())
166  <<"(TSOS.globalMomentum()) "<<(TSOS.globalMomentum());
167 
168  //initialization
169  //----------------------
170  // WARNING. this is mutable
171  // you should never remove this line
172  theFirstlayer=true;
174  //----------------------
175  int Nhits=0;
177  double z=0,r=0;
178  //flipping pair of list of trajectories
180  //initialize the head() of pair of list of trajectories
181  Trajectories.head().push_back(trajectory());
182  trajectory & initial = *Trajectories.head().rbegin();
183  initial.TSOS=TSOS;
184  initial.traj=basicTrajectory;
185 
186 
187 
188  //get the DetLayer in the tracker
189  std::vector<BarrelDetLayer*> tiblc = theMeasurementTracker->geometricSearchTracker()->tibLayers();
190  std::vector<BarrelDetLayer*> toblc = theMeasurementTracker->geometricSearchTracker()->tobLayers();
191  std::vector<ForwardDetLayer*> tidlc[2];
194  std::vector<ForwardDetLayer*> teclc[2];
197  const int Ntib=tiblc.size();
198  const int Ntob=toblc.size();
199  const int Ntid=tidlc[0].size();
200 
201 
202  const int Ntec=teclc[0].size();
203 
204  LogDebug(theCategory)<<"(Ntib) "<<(Ntib)<<"(Ntob) "<<(Ntob)<<"(Ntid) "<<(Ntid)<<"(Ntec) "<<(Ntec);
205 
206  const SimpleDiskBounds * sdbounds=0;
207 
208  position = TSOS.globalPosition();
209  z = position.z();
210  r = position.perp();
211 
212  //select which part we are in
213  enum PART { fault , PXB, PXF, TIB , TID , TOB , TEC};
214  PART whichpart = fault;
215  switch(detId.subdetId()){
216  case 1: {whichpart=PXB;break;}
217  case 2: {whichpart=PXF;break;}
218 
219  case 3: {whichpart=TIB;break;}
220  case 4: {whichpart=TID;break;}
221  case 5: {whichpart=TOB;break;}
222  case 6: {whichpart=TEC;break;}}
223 
224  bool inapart=true;
225  bool firstRound =true;
226  int indexinpart=0;
227  //loop while in a valid part of the tracker
228  while(inapart){
229 
230  //check on the trajectory list and stuff
231  if (!checkStep(Trajectories.head())) break;
232  //................
233 
234  switch (whichpart){
235 
236  case fault: /*abort*/ {edm::LogError(theCategory)<<"something's wrong with the seed";return;}
237  case PXB: /*abort*/ {edm::LogError(theCategory)<<"PXB no yet implemented";return;}
238  case PXF: /*abort*/ {edm::LogError(theCategory)<<"PXF no yet implemented";return;}
239 
240  //-------------- into TIB----------------
241  case TIB:{
242  if (indexinpart==Ntib){/*you have reach the last layer of the TIB.let's go to the TOB*/whichpart = TOB; indexinpart=-1;break; }
243 
244  LogDebug(theCategory)<<"within TIB "<<indexinpart+1;
245 
246  //propagate to corresponding surface
247  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),tiblc[indexinpart]->surface());
248  if (!TSOS.isValid()) {;break;} //go to the next one
249 
250  z=TSOS.globalPosition().z();
251 
252  //have we reached a boundary
253  if (fabs(z) > fabs(tidlc[(z>0)][0]->surface().position().z()))
254  {/*z bigger than the TID min z: go to TID*/
255  LogDebug(theCategory)<<"|z| ("<<z<<") bigger than the TID min z("<<tidlc[(z>0)][0]->surface().position().z()<<"): go to TID";
256  whichpart = TID; indexinpart=-1; break;}
257  else {/*gather hits in the corresponding TIB layer*/ Nhits+=GatherHits(TSOS,tiblc[indexinpart],Trajectories);}
258  break;}
259 
260  //-------------- into TID----------------
261  case TID: {
262  if (indexinpart==Ntid){/*you have reach the last layer of the TID. let's go to the TEC */ whichpart = TEC; indexinpart=-1; break;}
263 
264  LogDebug(theCategory)<<"within TID "<<indexinpart+1;
265 
266  //propagate to corresponding surface
267  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),tidlc[(z>0)][indexinpart]->surface());
268  if (!TSOS.isValid()){break;}//go to the next one
269 
270  position = TSOS.globalPosition();
271  z = position.z();
272  r = position.perp();
273 
274  sdbounds = dynamic_cast<const SimpleDiskBounds *>(&tidlc[(z>0)][indexinpart]->surface().bounds());
275  if (!sdbounds)/*abort*/{edm::LogError(theCategory)<<" detlayer bounds are not SimpleDiskBounds in tid geometry";return;}
276 
277  //have we reached a boundary
278  if (r < sdbounds->innerRadius())
279  {/*radius smaller than the TID disk inner radius: next disk please*/
280  LogDebug(theCategory)<<"radius ("<<r<<") smaller than the TID disk inner radius ("<<sdbounds->innerRadius()<<"): next disk please";
281  break;}
282  else if (r >sdbounds->outerRadius())
283  {/*radius bigger than the TID disk outer radius: go to TOB*/
284  LogDebug(theCategory)<<"radius ("<<r<<") bigger than the TID disk outer radius("<<sdbounds->outerRadius()<<"): go to TOB";
285  whichpart = TOB; indexinpart=-1;break;}
286  else {/*gather hits in the corresponding TIB layer*/
287  LogDebug(theCategory)<<"collecting hits";
288  Nhits+=GatherHits(TSOS,tidlc[(z>0)][indexinpart],Trajectories);}
289  break;}
290 
291  //-------------- into TOB----------------
292  case TOB: {
293  if (indexinpart==Ntob){/*you have reach the last layer of the TOB. this is an end*/ inapart=false;break;}
294 
295  LogDebug(theCategory)<<"within TOB "<<indexinpart+1;
296 
297  //propagate to corresponding surface
298  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),toblc[indexinpart]->surface());
299  if (!TSOS.isValid()) {break;} //go to the next one
300 
301  z = TSOS.globalPosition().z();
302 
303  //have we reached a boundary
304  if (fabs(z) > fabs(teclc[(z>0)][0]->surface().position().z()))
305  {/*z bigger than the TOB layer max z: go to TEC*/
306  LogDebug(theCategory)<<"|z| ("<<z<<") bigger than the TOB layer max z ("<< teclc[(z>0)][0]->surface().position().z()<<"): go to TEC";
307  whichpart = TEC; indexinpart=-1;break;}
308  else {/*gather hits in the corresponding TOB layer*/Nhits+=GatherHits(TSOS,toblc[indexinpart],Trajectories);}
309  break;}
310 
311  //-------------- into TEC----------------
312  case TEC: {
313  if (indexinpart==Ntec){/*you have reach the last layer of the TEC. let's end here*/inapart=false;break;}
314 
315  LogDebug(theCategory)<<"within TEC "<<indexinpart+1;
316 
317  //propagate to corresponding TEC disk
318  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),teclc[(z>0)][indexinpart]->surface());
319  if (!TSOS.isValid()) {break;} //go to the next one
320 
321  position = TSOS.globalPosition();
322  z = position.z();
323  r = position.perp();
324 
325  sdbounds = dynamic_cast<const SimpleDiskBounds *>(&teclc[(z>0)][indexinpart]->surface().bounds());
326  if (!sdbounds)/*abort*/ {edm::LogError(theCategory)<<" detlayer bounds are not SimpleDiskBounds in tec geometry";return;}
327 
328  //have we reached a boundary ?
329  if (r < sdbounds->innerRadius())
330  {/*radius smaller than the TEC disk inner radius: next disk please*/
331  LogDebug(theCategory)<<"radius ("<<r<<") smaller than the TEC disk inner radius ("<<sdbounds->innerRadius()<<"): next disk please";
332  break;}
333  else if (r > sdbounds->outerRadius())
334  {/*radius bigger than the TEC disk outer radius: I can stop here*/
335  LogDebug(theCategory)<<"radius ("<<r<<") bigger than the TEC disk outer radius ("<<sdbounds->outerRadius()<<"): I can stop here";
336  inapart=false;break;}
337  else {/*gather hits in the corresponding TEC layer*/Nhits+=GatherHits(TSOS,teclc[(z>0)][indexinpart],Trajectories);}
338 
339  break;}
340 
341  }//switch
342  indexinpart++;
343  firstRound=false;
344  }//while inapart
345 
346 
347  LogDebug(theCategory)<<"propagating through layers is done";
348 
349  //--------------------------------------- SWIMMING DONE --------------------------------------
350  //the list of trajectory has been build. let's find out which one is the best to use.
351 
352  edm::LogInfo(theCategory)<<"found: "
353  <<Nhits<<" hits in the road for this seed \n"
354  << Trajectories.head().size()<<" possible trajectory(ies)";
355 
356  if (Trajectories.head().empty()) /*abort*/{edm::LogError(theCategory)<<" no possible trajectory found"; return;}
357 
358  //order the list to put the best in front
359  Trajectories.head().sort(trajectoryOrder);
360 
361  //------------------------------------OUTPUT FILL---------------------------------------------
362  if (theOutputAllTraj) {
363  //output all the possible trajectories found, if they have enough hits on them
364  //the best is still the first
365  for (TrajectoryCollection::iterator tit = Trajectories.head().begin(); tit!=Trajectories.head().end();tit++)
366  {if (tit->measurements.size()>= theMinNumberOfHitOnCandidate){result.push_back(smooth(tit->traj));}}
367  }
368  else{
369  //output only the best one
370  trajectory & best = (*Trajectories.head().begin());
371  if (best.measurements.size()< theMinNumberOfHitOnCandidate)/*abort*/{edm::LogError(theCategory)<<"best trajectory does not have enough ("<<best.measurements.size()<<") hits on it (<"<<theMinNumberOfHitOnCandidate<<")"; return;}
372  //output only the best trajectory
373  result.push_back(smooth(best.traj));}
374 
375  edm::LogInfo(theCategory)<<result.size()<<" trajectory(ies) output";
376 }//makeTrajectories_0
377 
378 
380  {
381  // GlobalVector d= (meas_2.recHit()->globalPosition () - meas_1.recHit()->globalPosition ()).unit();
383 
384  GlobalVector u1= meas_1.predictedState().globalDirection().unit(); //was using only that before
386  GlobalVector u =(u1+u2)/2.; //the average momentum to be sure that the relation is symetrical.
387  return d.dot(u) > 0;
388  }
390  {return trajectorymeasurementOrder(meas_2,meas_1);}
391 
392 
393 
395  //remove the overlapping recHits since the smoother will chock on it
397 
398  const DetLayer* lastDetLayer =0;
399  Trajectory::DataContainer::iterator mit = meas.begin();
400  while (mit!=meas.end()){
401  {
402  const DetLayer * detLayer = theMeasurementTracker->geometricSearchTracker()->detLayer(mit->recHit()->det()->geographicalId());
403  LogDebug(theCategory)<<"(mit->recHit()->det()->geographicalId().rawId()) "<<(mit->recHit()->det()->geographicalId().rawId())
404  <<"(detLayer) "<<(detLayer)<<"(lastDetLayer) "<<(lastDetLayer);
405 
406  if (detLayer==lastDetLayer)
407  {
408  mit=meas.erase(mit); //serve as mit++ too
409  }
410  else {mit++;}
411  lastDetLayer=detLayer;
412  }
413  Trajectory newTraj(traj.seed(),traj.direction());
414  for (Trajectory::DataContainer::iterator mit=meas.begin();mit!=meas.end();++mit)
415  {newTraj.push(*mit);}
416  traj=newTraj;
417  }
418  }
419 
420 
423 
424  // edm::LogInfo(theCategory)<<"sorting ("<< meas.size() <<") measurements.";
425  //sort the measurements
426  if (traj.direction() == oppositeToMomentum)
427  {std::sort(meas.begin(),meas.end(),trajectorymeasurementInverseOrder);}
428  else
429  {std::sort(meas.begin(),meas.end(),trajectorymeasurementOrder);}
430 
431  //create a new one
432  Trajectory newTraj(traj.seed(),traj.direction());
433  for (Trajectory::DataContainer::iterator mit=meas.begin();mit!=meas.end();++mit)
434  {newTraj.push(*mit);}
435 
436  //exchange now.
437  traj = newTraj;
438  }
439 
441 
442  //need to order the list of measurements on the trajectory first
444 
445  std::vector<Trajectory> ret=theSmoother->trajectories(traj);
446 
447  if (ret.empty()){
448  edm::LogError(theCategory)<<"smoother returns an empty vector of trajectories: try cleaning first and resmooth";
449  cleanTrajectory(traj);
450  ret=theSmoother->trajectories(traj);
451  }
452 
453  if (ret.empty()){edm::LogError(theCategory)<<"smoother returns an empty vector of trajectories.";
454  return traj;}
455  else{return (ret.front());}
456 }
457 
458 //function called for each layer during propagation
460 {
462  bool atleastoneadded=false;
463  int Nhits=0;
464 
465  //find compatible modules
466  std::vector<DetLayer::DetWithState> compatible =thislayer->compatibleDets( step, *thePropagator , *theRoadEstimator);
467 
468  //loop over compatible modules
469  for (std::vector< DetLayer::DetWithState > ::iterator dws = compatible.begin();dws != compatible.end();dws++)
470  {
471  const DetId presentdetid = dws->first->geographicalId();//get the det Id
472  restep = dws->second;
473 
474 
475  LogDebug(theCategory)<<((dws->first->components ().size()!=0) ? /*stereo layer*/"double sided layer":/*single sided*/"single sided layer")
476  <<"(presentdetid.rawId()) "<<(presentdetid.rawId());
477 
478  //get the rechits on this module
480  int additionalHits =0;
481 
482  LogDebug(theCategory)<<"(thoseHits.size()) "<<(thoseHits.size());
483 
484  if (thoseHits.size()>theNumberOfHitPerModule)
486  <<" compatible hits ("<<thoseHits.size()<<")on module "<<presentdetid.rawId()
487  <<", skip it";continue; }
488 
489  //loop over the rechit on the module
490  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator iTThit = thoseHits.begin();iTThit != thoseHits.end(); iTThit++)
491  {
492  if (!(*iTThit)->isValid())/*skip*/{edm::LogInfo(theCategory)<<"rec hit not valid on module "<<presentdetid.rawId() <<". I skip it"; continue;}
493 
494  LogDebug(theCategory)<<((dynamic_cast<const SiStripMatchedRecHit2D *>((*iTThit)->hit())!=0) ? /*matched rechit*/ "matched rechit" : " r-phi rechit");
495 
496  //get the surface of the module Id
497  const BoundPlane & surface = (*iTThit)->det()->surface();
498 
499  //estimate the consistency
501 
502  LogDebug(theCategory)<<"(restep.globalPosition().perp()) "<<(restep.globalPosition().perp())<<"(restep.globalPosition().mag()) "<<(restep.globalPosition().mag())
503  <<"road step parameters at module: \n"<<restep
504  << "(est_road.first) "<<(est_road.first)<<"(est_road.second) "<<(est_road.second);
505 
506  //check consistency
507  if (est_road.first)
508  { //hit and propagation are consistent : gather the hit
509  Nhits++;
510  additionalHits++;
511  atleastoneadded=true;
512 
513  LogDebug(theCategory)<<"hit is consistent with road"<<"(presentdetid.rawId()) "<<(presentdetid.rawId())
514  <<"loop over previous trajectories\n"
515  <<"(Trajectories.tail().size()) "<<(Trajectories.tail().size())<<"(Trajectories.head().size()) "<<(Trajectories.head().size());
516 
517  //update the list of trajectory that we have with the consistent rechit.
518  //loop over the existing list of trajectories and add the hit if necessary
519  for ( TrajectoryCollection::iterator traj =Trajectories.head().begin();traj != Trajectories.head().end(); traj++)
520  {
521  //what is the previous state for this trajectory
522  const TrajectoryStateOnSurface & previousState = traj->TSOS;
523  if (!previousState.isValid())
524  {edm::LogError(theCategory)<<"previous free state is invalid at trajectory update, this is WRONG"; continue;}
525  const FreeTrajectoryState & previousFreestate = *previousState.freeState();
526 
527  //propagate it to the current surface
528  TrajectoryStateOnSurface predictedState = thePropagator->propagate(previousFreestate,surface);
529  if (!predictedState.isValid())/*skip*/{edm::LogError(theCategory)
530  <<"predicted state is not valid at trajectory update, rechit surface cannot be reached by the previous updated state.";continue;}
531 
533  est= theHitEstimator->estimate(predictedState,**iTThit);
534 
535  LogDebug(theCategory)<<"(est.first) "<<(est.first)<<"(est.second) "<<(est.second);
536 
537  //is the current hit consistent with the trajectory
538  if (est.first )
539  {
540  //update the trajectory state with the rechit
541  const TrajectoryStateOnSurface & updatedState = theUpdator->update(predictedState,**iTThit);
542  if (!updatedState.isValid())/*skip*/{edm::LogError(theCategory)<<"updated state is not valid, this is really wrong";continue;}
543 
544  LogDebug(theCategory)<<"updating a previous state with a rechit";
545 
546  //add a combined trajectory to the new list of trajectory, starting from the existing trajecotry
547  Trajectories.tail().push_back(*traj); //from existing
548  trajectory & combined = (*Trajectories.tail().rbegin());
549  combined.duplicate =false; //this is important
550  //increment the chi2
551  //combined.chi2 += est.second;
552  combined.chi2 += est_road.second;//better to add the road chi2 too unbias the chi2 sum towards first hits
553  //some history about the trajectory
554  combined.lastmissed=false;
555  combined.missedinarow=0;
556  //add a new hits to the measurements
557  combined.measurements.push_back(TrajectoryMeasurement(updatedState,*iTThit));
558  TrajectoryMeasurement & trajMeasurement = (*combined.measurements.rbegin());
559  //assigne updated state
560  combined.TSOS = updatedState;
561  //add trajectory measurement
562  combined.traj.push(trajMeasurement,est.second);
563 
564  LogDebug(theCategory)<<"(combined.traj.foundHits()) "<<(combined.traj.foundHits())
565  <<"muon measurement on previous module: \n"<<traj->TSOS
566  <<"muon measurement before update: \n"<<predictedState
567  <<"muon measurement after update: \n"<<updatedState;
568 
569  }//hit consistent with trajectory
570  else
571  {
572  LogDebug(theCategory)<<"hit failed chi2 test for trajectories update\n"<<"(traj->duplicate) "<<(traj->duplicate);
573 
574  if (!traj->duplicate){
575  Trajectories.tail().push_back(*traj);
576  trajectory & copied = (*Trajectories.tail().rbegin());
577  copied.missed++;
578  copied.lastmissed=true;
579  copied.missedinarow++;
580  traj->duplicate =true; //set this trajectory to already have been copied into next step
581  }//not a duplicate trajectory
582  }//hit not consistent with trajectory
583  }//existing trajectories loop
584  }//hit is consistent with muon road
585  }//rechits on module loop
586 
587 
588  //discard previous list of trajectories
589  //if something as been done of course
590  if (!Trajectories.tail().empty())
591  {
592  //if this is not the first "layer" of detector, set updated trajectories as new seed trajectories
593  //will branch on every single rechit uncountered for first "layer"
595  {
596  LogDebug(theCategory)<<"swapping trajectory list index";
597 
598  //always carry on the <IP> alone state in the next list of trajectories to avoid bias from the first rechits
600  {
601  LogDebug(theCategory)<<"push front <IP> to next list of trajectories";
602 
603  Trajectories.tail().push_front(*Trajectories.head().begin()); //[0] is <IP> always
604  trajectory & pushed = *Trajectories.tail().begin();
605  pushed.missed+=additionalHits;
606  pushed.lastmissed = ( additionalHits!=0);
607  pushed.missedinarow++;
608  }
609  //FIXME, there is a candidate leak at this point
610  //if the IP state is carried on at first layer, without update, then it will be duplicated. this is very unlikely though
611 
612  Trajectories.head().clear();
613 
614  //swap the lists
615  Trajectories.flip();
616  }
617  }//discard previous list of trajectories
618  }//module loop
619 
620 
621 
622  //do some cleaning of the list of trajectories
623  if(theFirstlayer && atleastoneadded )
624  {
625  theFirstlayer =false; //we are not in the first layer if something has been added
627  {
628  LogDebug(theCategory)<<"swapping trajectory list index (end of first layer)";
629 
630  //and for consistency, you have to swap index here, because it could ahve not been done in the module loop above
631  //always carry on the <IP> alone state in the next list of trajectories to avoid bias from the first rechits
633  {Trajectories.tail().push_front(*Trajectories.head().begin());} //[0] is <IP> always at this stage
634  //FIXME, there is a candidate leak at this point
635  //if the IP state is carried on at first layer, without update, then it will be duplicated. this is very unlikely though
636 
637  Trajectories.head().clear();
638  //swap the switch
639  Trajectories.flip();
640  }
641  else
642  {
643  //actually remove the <IP> from first postion of the next source of trajectories
644  //since the swaping has already been done. pop up from theTrajectorysource, not !theTrajectorysource
645  //only if it has been done at the first layer module though
647 
648  LogDebug(theCategory)<<"pop up <IP> from trajectories";
649 
650  Trajectories.head().pop_front(); }
651  }
652 
653 
654  //check an remove trajectories that are subset of the other in next source
655  //after the first layer only
656  if (Trajectories.head().size()>=2)
657  {checkDuplicate(Trajectories.head());}
658 
659  } //do some cleaning of the list of trajectories
660  return Nhits;
661 
662 }
663 
664 
666 {
667  //dynamic cut on the max number of rechit allowed on a single module
669  for (unsigned int vit = 0; vit!= theMaxTrajectoriesThreshold.size() ; vit++){
670  if (collection.size() >theMaxTrajectoriesThreshold[vit]){
672  else
673  break;}}
674 
675  //reduce the number of possible trajectories if too many
676  if ( collection.size() > theMaxTrajectories) {
677  //order with most hits or best chi2
678  collection.sort(trajectoryOrder);
679  unsigned int prevSize=collection.size();
680  collection.resize(theMaxTrajectories);
682  <<" too many possible trajectories ("<<prevSize
683  <<"), reduce the possibilities to "<<theMaxTrajectories<<" bests.";
684  }
685  return true;
686 }
687 
689 {
690  LogDebug(theCategory)<<"checking for duplicates here. list size: "<<collection.size();
691 
692  //loop over the trajectory list
693  TrajectoryCollection::iterator traj1 = collection.begin();
694  while(traj1 != collection.end())
695  {
696  LogDebug(theCategory)<<"";
697 
698  //reloop over the trajectory list from traj1
699  TrajectoryCollection::iterator traj2 = traj1;
700  traj2++;//advance one more
701  bool traj1_removed=false;
702  while( traj2 != collection.end())
703  {
704  if (traj2 == traj1 ) continue; //skip itself of course
705 
706  //need to start from the back of the list of measurment
707  std::list <TrajectoryMeasurement >::reverse_iterator h1 = traj1->measurements.rbegin();
708  std::list <TrajectoryMeasurement >::reverse_iterator h2 = traj2->measurements.rbegin();
709 
710  bool break_different = false;
711  while (h1 != traj1->measurements.rend() && h2!=traj2->measurements.rend())
712  {
715 
716  LogDebug(theCategory)<<"(hit1->geographicalId().rawId()) "<<(hit1->geographicalId().rawId())<<"(hit1->globalPosition()) "<<(hit1->globalPosition())
717  <<"(hit2->geographicalId().rawId()) "<<(hit2->geographicalId().rawId())<<"(hit2->globalPosition()) "<<(hit2->globalPosition());
718 
719  if (hit1 == hit2){/*those are common hits, everything's alright so far*/ h1++;h2++; continue;}
720  else{break_different =true;
721 
722  LogDebug(theCategory)<<"list of hits are different";
723 
724  break;}
725  }
726  if (!break_different)
727  //meaning one of the list has been exhausted
728  //one list if the subset of the other
729  {
730  LogDebug(theCategory)<<"list of hits are identical/subset. remove one of them.";
731  //there is a common subset to the two list of rechits.
732  //remove the one with the fewer hits (iterator that reached the end first)
733  //in case they are exactly identical (both iterator reached the end at the same time), traj2 will be removed by default
734  if (h1 != traj1->measurements.rend())
735  {
736  LogDebug(theCategory)<<"I removed traj2";
737  //traj2 has been exhausted first. remove it and place the iterator on next item
738  traj2=collection.erase(traj2);
739  }
740  else
741  {
742  LogDebug(theCategory)<<"I removed traj1. and decrement traj2";
743  //traj1 has been exhausted first. remove it
744  traj1=collection.erase(traj1);
745  //and set the iterator traj1 so that next++ will set it to the correct place in the list
746  traj1_removed=true;
747  break; // break the traj2 loop, advance to next traj1 item
748  }
749  }
750  else
751  {traj2++; }
752  }//loop on traj2
753  if (!traj1_removed)
754  {//increment only if you have remove the item at traj1
755  traj1++;}
756  }//loop on traj1
757 }
758 
759 
760 //CTF tool implementation
761 //first find the collection of rechits, then do something about it
762 void MuonRoadTrajectoryBuilder::makeTrajectories_1(const TrajectorySeed & seed, std::vector<Trajectory> & result) const
763 {
764  Trajectory basicTrajectory(seed,alongMomentum);
765  //add the muon system measurement to the basicTrajectory
766  //...
767 
768 // //build the trajectories
769 // std::vector<Trajectory> unsmoothed = theCkfbuilder->trajectories(seed);
770 
771 // //smoothed them
772 // if (theOutputAllTraj) {
773 // for (std::vector<Trajectory>::iterator tit = unsmoothed.begin(); tit!=unsmoothed.end();tit++)
774 // {result.push_back(smooth(*tit));}
775 // }
776 // else{
777 // //output only the first one
778 // result.push_back(smooth(unsmoothed.front()));}
779 
780 }
781 
#define LogDebug(id)
std::vector< Trajectory > Trajectories
T getParameter(std::string const &) const
int foundHits() const
Definition: Trajectory.h:224
bool trajectorymeasurementInverseOrder(const TrajectoryMeasurement &meas_1, const TrajectoryMeasurement &meas_2)
T perp() const
Definition: PV3DBase.h:71
virtual void update(const edm::Event &) const =0
std::vector< unsigned int > theMaxTrajectoriesThreshold
TrajectorySeed const & seed() const
Access to the seed used to reconstruct the Trajectory.
Definition: Trajectory.h:265
list step
Definition: launcher.py:15
std::string theCategory
Info/Debug category &quot;Muon|RecoMuon|MuonRoadTrajectoryBuilder&quot;.
virtual TrajectoryStateOnSurface update(const TrajectoryStateOnSurface &, const TransientTrackingRecHit &) const =0
MuonRoadTrajectoryBuilder(const edm::ParameterSet &par, const MeasurementTracker *mt, const MagneticField *f, const Propagator *p)
constructor from PSet and things from record
std::vector< Trajectory > trajectories(const TrajectorySeed &seed) const
bool trajectoryOrder(const MuonRoadTrajectoryBuilder::trajectory &traj1, const MuonRoadTrajectoryBuilder::trajectory &traj2)
GlobalPoint globalPosition() const
void makeTrajectories(const TrajectorySeed &seed, std::vector< Trajectory > &result, int version=0) const
KFTrajectorySmoother * theSmoother
PreciseFloatType< T, U >::Type dot(const Vector3DBase< U, FrameTag > &v) const
Definition: Vector3DBase.h:107
Trajectory smooth(Trajectory &) const
std::vector< ForwardDetLayer * > const & posTecLayers() const
std::vector< unsigned int > theNumberOfHitPerModuleThreshold
Chi2MeasurementEstimator * theHitEstimator
double double double z
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
bool checkStep(TrajectoryCollection &collection) const
tuple s2
Definition: indexGen.py:106
void makeTrajectories_0(const TrajectorySeed &seed, std::vector< Trajectory > &result) const
PropagationDirection const & direction() const
Definition: Trajectory.cc:195
uint32_t rawId() const
get the raw id
Definition: DetId.h:45
virtual std::vector< Trajectory > trajectories(const Trajectory &aTraj) const
std::vector< ForwardDetLayer * > const & negTecLayers() const
virtual RecHitContainer recHits(const TrajectoryStateOnSurface &) const =0
DataContainer const & measurements() const
Definition: Trajectory.h:203
void setEvent(const edm::Event &) const
int iEvent
Definition: GenABIO.cc:243
std::vector< Trajectory > TrajectoryContainer
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
T mag() const
Definition: PV3DBase.h:66
void cleanTrajectory(Trajectory &traj) const
FreeTrajectoryState * freeState(bool withErrors=true) const
string unit
Definition: csvLumiCalc.py:46
T sqrt(T t)
Definition: SSEVec.h:46
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
TrajectoryStateUpdator * theUpdator
const DetLayer * detLayer(const DetId &id) const
obsolete method. Use idToLayer() instead.
double f[11][100]
const TrackingGeometry * geomTracker() const
unsigned int detId() const
void makeTrajectories_1(const TrajectorySeed &seed, std::vector< Trajectory > &result) const
TrajectoryStateOnSurface predictedState() const
float outerRadius() const
const MeasurementTracker * theMeasurementTracker
void sortTrajectoryMeasurements(Trajectory &traj)
virtual std::pair< bool, double > estimate(const TrajectoryStateOnSurface &, const TransientTrackingRecHit &) const
virtual TrajectoryStateOnSurface propagate(const FreeTrajectoryState &, const Surface &) const
Definition: Propagator.cc:12
std::list< TrajectoryMeasurement > measurements
std::vector< ConstRecHitPointer > ConstRecHitContainer
Vector3DBase unit() const
Definition: Vector3DBase.h:57
Definition: DetId.h:20
std::pair< bool, double > HitReturnType
TrajectoryStateOnSurface TSOS
Definition: TestHits.cc:23
PTrajectoryStateOnDet const & startingState() const
TrajectoryStateOnSurface transientState(const PTrajectoryStateOnDet &ts, const Surface *surface, const MagneticField *field)
virtual const GeomDet * idToDet(DetId) const =0
std::list< trajectory > TrajectoryCollection
Chi2MeasurementEstimator * theRoadEstimator
std::vector< BarrelDetLayer * > const & tibLayers() const
GlobalVector globalMomentum() const
const BoundPlane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
std::vector< ForwardDetLayer * > const & posTidLayers() const
bool trajectorymeasurementOrder(const TrajectoryMeasurement &meas_1, const TrajectoryMeasurement &meas_2)
static int position[264][3]
Definition: ReadPGInfo.cc:509
virtual const MeasurementDet * idToDet(const DetId &id) const =0
MeasurementDetSystem interface.
std::vector< ForwardDetLayer * > const & negTidLayers() const
float innerRadius() const
Extension of the Bounds interface.
const GeometricSearchTracker * geometricSearchTracker() const
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:35
void checkDuplicate(TrajectoryCollection &collection) const
GlobalVector globalDirection() const
std::vector< BarrelDetLayer * > const & tobLayers() const
int GatherHits(const TrajectoryStateOnSurface &step, const DetLayer *thislayer, TrajectoryCollectionFPair &Trajectories) const