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 
11 
19 
20 //#include <DataFormats/GeometrySurface/interface/LocalError.h> //does not exist anymore...
23 
27 
28 //#include <RecoMuon/TrackingTools/interface/VertexRecHit.h>
30 
33 
36 
37 //alternative constructor
39  const MeasurementTracker * mt,
40  const MagneticField * f,
41  const Propagator * p):
42  theRoadEstimator(0),theHitEstimator(0),theUpdator(0),theSmoother(0)
43 {
44 
46  theMeasurementTrackerEvent = 0; // YES this will crash, Will fix later.
47  theField = f;
48  thePropagator = p;
49 
50  theCategory = "Muon|RecoMuon|MuonRoadTrajectoryBuilder";
51 
52  //get parameters from ParameterSet
53 
54  //propagator name to get from muon service
55  // thePropagatorName = iConfig.getParameter<std::string>("propagatorName");
56 
57  //chi2 estimator
58  double chi2R=iConfig.getParameter<double>("maxChi2Road");
60  double chi2H=iConfig.getParameter<double>("maxChi2Hit");
61  theHitEstimator = new Chi2MeasurementEstimator(chi2H,sqrt(chi2H));
62 
63  //trajectory updator
64  theUpdator= new KFUpdator();
65 
66  //limit the total number of possible trajectories taken into account for a single seed
67  theMaxTrajectories = iConfig.getParameter<unsigned int>("maxTrajectories");
68 
69  //limit the type of module considered to gather rechits
70  theDynamicMaxNumberOfHitPerModule = iConfig.getParameter<bool>("dynamicMaxNumberOfHitPerModule");
71  theNumberOfHitPerModuleDefault = iConfig.getParameter<unsigned int>("numberOfHitPerModule");
72  theMaxTrajectoriesThreshold = iConfig.getParameter<std::vector<unsigned int> >("maxTrajectoriesThreshold");
73  theNumberOfHitPerModuleThreshold = iConfig.getParameter<std::vector<unsigned int> >("numberOfHitPerModuleThreshold");
74 
75  //could be configurable, but not
79 
80  //output track candidate selection
81  theMinNumberOfHitOnCandidate = iConfig.getParameter<unsigned int>("minNumberOfHitOnCandidate");
82 
83  //single or multiple trajectories per muon
84  theOutputAllTraj = iConfig.getParameter<bool>("outputAllTraj");
85 
86  if (!theSmoother)
88 }
89 
90 //destructor
92 {
93  edm::LogInfo(theCategory)<<"cleaning the object";
95  if (theHitEstimator) delete theHitEstimator;
96  if (theUpdator) delete theUpdator;
97  if (theSmoother) delete theSmoother;
99 }
100 
102 }
103 
104 
105 
106 
108 { //order so that first element of the list have
109  //most hits, if equal smallest chi2
110  unsigned int s1=traj1.measurements.size();
111  unsigned int s2=traj2.measurements.size();
112  if (s1>s2) return true; //decreasing order of measurements.size()
113  else {
114  if (s1==s2) return (traj1.chi2<traj2.chi2); //increase order of chi2
115  else return false; }}
116 
117 
119 {
120  LogDebug(theCategory)<<"makeTrajectories START";
121  //process the seed through the tracker
122  makeTrajectories(seed,ret);
123 }
124 
125 //reconstruct trajectory for the trajectory seed
126 std::vector<Trajectory> MuonRoadTrajectoryBuilder::trajectories(const TrajectorySeed & seed) const
127 {
128  LogDebug(theCategory)<<"makeTrajectories START";
129 
130  //default output
131  std::vector<Trajectory> result;
132 
133  //process the seed through the tracker
134  makeTrajectories(seed,result);
135 
136  //output the result of regional tracking
137  return result;
138 }
139 
140 
141 
142 void MuonRoadTrajectoryBuilder::makeTrajectories(const TrajectorySeed & seed, std::vector<Trajectory> & result,int version) const
143 { if (version==0) { makeTrajectories_0(seed,result);}
144  else if (version==1) { makeTrajectories_1(seed,result);}}
145 
146 
147 //home grown tools
148 //old implementation
149 void MuonRoadTrajectoryBuilder::makeTrajectories_0(const TrajectorySeed & seed, std::vector<Trajectory> & result) const
150 {
151  Trajectory basicTrajectory(seed,alongMomentum);
152  //add the muon system measurement to the basicTrajectory
153  //...no yet implemented...
154 
155  //get the initial state
156  PTrajectoryStateOnDet PTstart=seed.startingState();
157  DetId detId(PTstart.detId());
158  const BoundPlane * surface =(&theMeasurementTracker->geomTracker()->idToDet(detId)->surface());
159  //start from this point
161  if (!TSOS.isValid())/*/abort*/{ edm::LogError(theCategory)<<"TSOS from PTSOD is not valid.";return ;}
162 
163  LogDebug(theCategory) <<"(detId.rawId()) "<<(detId.rawId())<<"(detId.subdetId()) "<<(detId.subdetId())
164  <<"(TSOS.globalPosition()) "<<(TSOS.globalPosition())
165  <<"(TSOS.globalMomentum()) "<<(TSOS.globalMomentum());
166 
167  //initialization
168  //----------------------
169  //
170  //
171  bool theFirstlayer=true;
172  unsigned int theNumberOfHitPerModule = theNumberOfHitPerModuleDefault;
173  //----------------------
174  int Nhits=0;
176  double z=0,r=0;
177  //flipping pair of list of trajectories
179  //initialize the head() of pair of list of trajectories
180  Trajectories.head().push_back(trajectory());
181  trajectory & initial = *Trajectories.head().rbegin();
182  initial.TSOS=TSOS;
183  initial.traj=basicTrajectory;
184 
185 
186 
187  //get the DetLayer in the tracker
188  std::vector<BarrelDetLayer*> tiblc = theMeasurementTracker->geometricSearchTracker()->tibLayers();
189  std::vector<BarrelDetLayer*> toblc = theMeasurementTracker->geometricSearchTracker()->tobLayers();
190  std::vector<ForwardDetLayer*> tidlc[2];
193  std::vector<ForwardDetLayer*> teclc[2];
196  const int Ntib=tiblc.size();
197  const int Ntob=toblc.size();
198  const int Ntid=tidlc[0].size();
199 
200 
201  const int Ntec=teclc[0].size();
202 
203  LogDebug(theCategory)<<"(Ntib) "<<(Ntib)<<"(Ntob) "<<(Ntob)<<"(Ntid) "<<(Ntid)<<"(Ntec) "<<(Ntec);
204 
205  const SimpleDiskBounds * sdbounds=0;
206 
207  position = TSOS.globalPosition();
208  z = position.z();
209  r = position.perp();
210 
211  //select which part we are in
212  enum PART { fault , PXB, PXF, TIB , TID , TOB , TEC};
213  PART whichpart = fault;
214  switch(detId.subdetId()){
215  case 1: {whichpart=PXB;break;}
216  case 2: {whichpart=PXF;break;}
217 
218  case 3: {whichpart=TIB;break;}
219  case 4: {whichpart=TID;break;}
220  case 5: {whichpart=TOB;break;}
221  case 6: {whichpart=TEC;break;}}
222 
223  bool inapart=true;
224  bool firstRound =true;
225  int indexinpart=0;
226  //loop while in a valid part of the tracker
227  while(inapart){
228 
229  //check on the trajectory list and stuff
230  if (!checkStep(Trajectories.head(),theNumberOfHitPerModule)) break;
231  //................
232 
233  switch (whichpart){
234 
235  case fault: /*abort*/ {edm::LogError(theCategory)<<"something's wrong with the seed";return;}
236  case PXB: /*abort*/ {edm::LogError(theCategory)<<"PXB no yet implemented";return;}
237  case PXF: /*abort*/ {edm::LogError(theCategory)<<"PXF no yet implemented";return;}
238 
239  //-------------- into TIB----------------
240  case TIB:{
241  if (indexinpart==Ntib){/*you have reach the last layer of the TIB.let's go to the TOB*/whichpart = TOB; indexinpart=-1;break; }
242 
243  LogDebug(theCategory)<<"within TIB "<<indexinpart+1;
244 
245  //propagate to corresponding surface
246  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),tiblc[indexinpart]->surface());
247  if (!TSOS.isValid()) {;break;} //go to the next one
248 
249  z=TSOS.globalPosition().z();
250 
251  //have we reached a boundary
252  if (fabs(z) > fabs(tidlc[(z>0)][0]->surface().position().z()))
253  {/*z bigger than the TID min z: go to TID*/
254  LogDebug(theCategory)<<"|z| ("<<z<<") bigger than the TID min z("<<tidlc[(z>0)][0]->surface().position().z()<<"): go to TID";
255  whichpart = TID; indexinpart=-1; break;}
256  else {/*gather hits in the corresponding TIB layer*/ Nhits+=GatherHits(TSOS,tiblc[indexinpart],Trajectories,theFirstlayer,theNumberOfHitPerModule);}
257  break;}
258 
259  //-------------- into TID----------------
260  case TID: {
261  if (indexinpart==Ntid){/*you have reach the last layer of the TID. let's go to the TEC */ whichpart = TEC; indexinpart=-1; break;}
262 
263  LogDebug(theCategory)<<"within TID "<<indexinpart+1;
264 
265  //propagate to corresponding surface
266  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),tidlc[(z>0)][indexinpart]->surface());
267  if (!TSOS.isValid()){break;}//go to the next one
268 
269  position = TSOS.globalPosition();
270  z = position.z();
271  r = position.perp();
272 
273  sdbounds = dynamic_cast<const SimpleDiskBounds *>(&tidlc[(z>0)][indexinpart]->surface().bounds());
274  if (!sdbounds)/*abort*/{edm::LogError(theCategory)<<" detlayer bounds are not SimpleDiskBounds in tid geometry";return;}
275 
276  //have we reached a boundary
277  if (r < sdbounds->innerRadius())
278  {/*radius smaller than the TID disk inner radius: next disk please*/
279  LogDebug(theCategory)<<"radius ("<<r<<") smaller than the TID disk inner radius ("<<sdbounds->innerRadius()<<"): next disk please";
280  break;}
281  else if (r >sdbounds->outerRadius())
282  {/*radius bigger than the TID disk outer radius: go to TOB*/
283  LogDebug(theCategory)<<"radius ("<<r<<") bigger than the TID disk outer radius("<<sdbounds->outerRadius()<<"): go to TOB";
284  whichpart = TOB; indexinpart=-1;break;}
285  else {/*gather hits in the corresponding TIB layer*/
286  LogDebug(theCategory)<<"collecting hits";
287  Nhits+=GatherHits(TSOS,tidlc[(z>0)][indexinpart],Trajectories,theFirstlayer,theNumberOfHitPerModule);}
288  break;}
289 
290  //-------------- into TOB----------------
291  case TOB: {
292  if (indexinpart==Ntob){/*you have reach the last layer of the TOB. this is an end*/ inapart=false;break;}
293 
294  LogDebug(theCategory)<<"within TOB "<<indexinpart+1;
295 
296  //propagate to corresponding surface
297  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),toblc[indexinpart]->surface());
298  if (!TSOS.isValid()) {break;} //go to the next one
299 
300  z = TSOS.globalPosition().z();
301 
302  //have we reached a boundary
303  if (fabs(z) > fabs(teclc[(z>0)][0]->surface().position().z()))
304  {/*z bigger than the TOB layer max z: go to TEC*/
305  LogDebug(theCategory)<<"|z| ("<<z<<") bigger than the TOB layer max z ("<< teclc[(z>0)][0]->surface().position().z()<<"): go to TEC";
306  whichpart = TEC; indexinpart=-1;break;}
307  else {/*gather hits in the corresponding TOB layer*/Nhits+=GatherHits(TSOS,toblc[indexinpart],Trajectories,theFirstlayer,theNumberOfHitPerModule);}
308  break;}
309 
310  //-------------- into TEC----------------
311  case TEC: {
312  if (indexinpart==Ntec){/*you have reach the last layer of the TEC. let's end here*/inapart=false;break;}
313 
314  LogDebug(theCategory)<<"within TEC "<<indexinpart+1;
315 
316  //propagate to corresponding TEC disk
317  if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),teclc[(z>0)][indexinpart]->surface());
318  if (!TSOS.isValid()) {break;} //go to the next one
319 
320  position = TSOS.globalPosition();
321  z = position.z();
322  r = position.perp();
323 
324  sdbounds = dynamic_cast<const SimpleDiskBounds *>(&teclc[(z>0)][indexinpart]->surface().bounds());
325  if (!sdbounds)/*abort*/ {edm::LogError(theCategory)<<" detlayer bounds are not SimpleDiskBounds in tec geometry";return;}
326 
327  //have we reached a boundary ?
328  if (r < sdbounds->innerRadius())
329  {/*radius smaller than the TEC disk inner radius: next disk please*/
330  LogDebug(theCategory)<<"radius ("<<r<<") smaller than the TEC disk inner radius ("<<sdbounds->innerRadius()<<"): next disk please";
331  break;}
332  else if (r > sdbounds->outerRadius())
333  {/*radius bigger than the TEC disk outer radius: I can stop here*/
334  LogDebug(theCategory)<<"radius ("<<r<<") bigger than the TEC disk outer radius ("<<sdbounds->outerRadius()<<"): I can stop here";
335  inapart=false;break;}
336  else {/*gather hits in the corresponding TEC layer*/Nhits+=GatherHits(TSOS,teclc[(z>0)][indexinpart],Trajectories,theFirstlayer,theNumberOfHitPerModule);}
337 
338  break;}
339 
340  }//switch
341  indexinpart++;
342  firstRound=false;
343  }//while inapart
344 
345 
346  LogDebug(theCategory)<<"propagating through layers is done";
347 
348  //--------------------------------------- SWIMMING DONE --------------------------------------
349  //the list of trajectory has been build. let's find out which one is the best to use.
350 
351  edm::LogInfo(theCategory)<<"found: "
352  <<Nhits<<" hits in the road for this seed \n"
353  << Trajectories.head().size()<<" possible trajectory(ies)";
354 
355  if (Trajectories.head().empty()) /*abort*/{edm::LogError(theCategory)<<" no possible trajectory found"; return;}
356 
357  //order the list to put the best in front
358  Trajectories.head().sort(trajectoryOrder);
359 
360  //------------------------------------OUTPUT FILL---------------------------------------------
361  if (theOutputAllTraj) {
362  //output all the possible trajectories found, if they have enough hits on them
363  //the best is still the first
364  for (TrajectoryCollection::iterator tit = Trajectories.head().begin(); tit!=Trajectories.head().end();tit++)
365  {if (tit->measurements.size()>= theMinNumberOfHitOnCandidate){result.push_back(smooth(tit->traj));}}
366  }
367  else{
368  //output only the best one
369  trajectory & best = (*Trajectories.head().begin());
370  if (best.measurements.size()< theMinNumberOfHitOnCandidate)/*abort*/{edm::LogError(theCategory)<<"best trajectory does not have enough ("<<best.measurements.size()<<") hits on it (<"<<theMinNumberOfHitOnCandidate<<")"; return;}
371  //output only the best trajectory
372  result.push_back(smooth(best.traj));}
373 
374  edm::LogInfo(theCategory)<<result.size()<<" trajectory(ies) output";
375 }//makeTrajectories_0
376 
377 
379  {
380  // GlobalVector d= (meas_2.recHit()->globalPosition () - meas_1.recHit()->globalPosition ()).unit();
382 
383  GlobalVector u1= meas_1.predictedState().globalDirection().unit(); //was using only that before
385  GlobalVector u =(u1+u2)/2.; //the average momentum to be sure that the relation is symetrical.
386  return d.dot(u) > 0;
387  }
389  {return trajectorymeasurementOrder(meas_2,meas_1);}
390 
391 
392 
394  //remove the overlapping recHits since the smoother will chock on it
396 
397  const DetLayer* lastDetLayer =0;
398  Trajectory::DataContainer::iterator mit = meas.begin();
399  while (mit!=meas.end()){
400  {
401  const DetLayer * detLayer = theMeasurementTracker->geometricSearchTracker()->detLayer(mit->recHit()->det()->geographicalId());
402  LogDebug(theCategory)<<"(mit->recHit()->det()->geographicalId().rawId()) "<<(mit->recHit()->det()->geographicalId().rawId())
403  <<"(detLayer) "<<(detLayer)<<"(lastDetLayer) "<<(lastDetLayer);
404 
405  if (detLayer==lastDetLayer)
406  {
407  mit=meas.erase(mit); //serve as mit++ too
408  }
409  else {mit++;}
410  lastDetLayer=detLayer;
411  }
412  Trajectory newTraj(traj.seed(),traj.direction());
413  for (Trajectory::DataContainer::iterator mit=meas.begin();mit!=meas.end();++mit)
414  {newTraj.push(*mit);}
415  traj=newTraj;
416  }
417  }
418 
419 
422 
423  // edm::LogInfo(theCategory)<<"sorting ("<< meas.size() <<") measurements.";
424  //sort the measurements
425  if (traj.direction() == oppositeToMomentum)
426  {std::sort(meas.begin(),meas.end(),trajectorymeasurementInverseOrder);}
427  else
428  {std::sort(meas.begin(),meas.end(),trajectorymeasurementOrder);}
429 
430  //create a new one
431  Trajectory newTraj(traj.seed(),traj.direction());
432  for (Trajectory::DataContainer::iterator mit=meas.begin();mit!=meas.end();++mit)
433  {newTraj.push(*mit);}
434 
435  //exchange now.
436  traj = newTraj;
437  }
438 
440 
441  //need to order the list of measurements on the trajectory first
443 
444  std::vector<Trajectory> ret=theSmoother->trajectories(traj);
445 
446  if (ret.empty()){
447  edm::LogError(theCategory)<<"smoother returns an empty vector of trajectories: try cleaning first and resmooth";
448  cleanTrajectory(traj);
449  ret=theSmoother->trajectories(traj);
450  }
451 
452  if (ret.empty()){edm::LogError(theCategory)<<"smoother returns an empty vector of trajectories.";
453  return traj;}
454  else{return (ret.front());}
455 }
456 
457 //function called for each layer during propagation
459  bool & theFirstlayer, unsigned int theNumberOfHitPerModule) const
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)
485  { edm::LogInfo(theCategory)<<"more than "<<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
500  MeasurementEstimator::HitReturnType est_road = theRoadEstimator->estimate(restep,**iTThit);
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  const 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"
594  if (!theFirstlayer || theBranchonfirstlayer)
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
599  if (theFirstlayer && theCarriedIPatfirstlayerModule)
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 
665 bool MuonRoadTrajectoryBuilder::checkStep(TrajectoryCollection & collection, unsigned int & theNumberOfHitPerModule) const
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]){
671  theNumberOfHitPerModule= theNumberOfHitPerModuleThreshold[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 >::const_reverse_iterator h1 = traj1->measurements.rbegin();
708  std::list <TrajectoryMeasurement >::const_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
MeasurementDetWithData idToDet(const DetId &id) const
Previous MeasurementDetSystem interface.
int foundHits() const
Definition: Trajectory.h:236
TrajectoryStateOnSurface const & predictedState() const
bool trajectorymeasurementInverseOrder(const TrajectoryMeasurement &meas_1, const TrajectoryMeasurement &meas_2)
T perp() const
Definition: PV3DBase.h:72
std::vector< unsigned int > theMaxTrajectoriesThreshold
TrajectorySeed const & seed() const
Access to the seed used to reconstruct the Trajectory.
Definition: Trajectory.h:277
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
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
float float float z
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
const MeasurementTrackerEvent * theMeasurementTrackerEvent
tuple s2
Definition: indexGen.py:106
void makeTrajectories_0(const TrajectorySeed &seed, std::vector< Trajectory > &result) const
PropagationDirection const & direction() const
Definition: Trajectory.cc:196
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
std::vector< ForwardDetLayer * > const & negTecLayers() const
DataContainer const & measurements() const
Definition: Trajectory.h:215
void setEvent(const edm::Event &) const
RecHitContainer recHits(const TrajectoryStateOnSurface &tsos) 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:67
void cleanTrajectory(Trajectory &traj) const
string unit
Definition: csvLumiCalc.py:46
int GatherHits(const TrajectoryStateOnSurface &step, const DetLayer *thislayer, TrajectoryCollectionFPair &Trajectories, bool &firstLayer, unsigned int theNumberOfHitPerModule) const
T sqrt(T t)
Definition: SSEVec.h:48
FreeTrajectoryState const * freeState(bool withErrors=true) const
T z() const
Definition: PV3DBase.h:64
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
const MeasurementTracker * theMeasurementTracker
void sortTrajectoryMeasurements(Trajectory &traj)
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:18
std::pair< bool, double > HitReturnType
TrajectoryStateOnSurface TSOS
Definition: TestHits.cc:19
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
return(e1-e2)*(e1-e2)+dp *dp
Chi2MeasurementEstimator * theRoadEstimator
std::vector< BarrelDetLayer * > const & tibLayers() const
GlobalVector globalMomentum() const
std::vector< ForwardDetLayer * > const & posTidLayers() const
bool trajectorymeasurementOrder(const TrajectoryMeasurement &meas_1, const TrajectoryMeasurement &meas_2)
std::vector< ForwardDetLayer * > const & negTidLayers() const
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
bool checkStep(TrajectoryCollection &collection, unsigned int &theNumberOfHitPerModule) const