CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GlobalCosmicMuonTrajectoryBuilder.cc
Go to the documentation of this file.
1 
11 
14 
23 
24 using namespace std;
25 using namespace edm;
26 
27 //
28 // constructor
29 //
31  const MuonServiceProxy* service,edm::ConsumesCollector& iC) : theService(service) {
32  ParameterSet smootherPSet = par.getParameter<ParameterSet>("SmootherParameters");
33  theSmoother = new CosmicMuonSmoother(smootherPSet,theService);
34 
35  ParameterSet trackMatcherPSet = par.getParameter<ParameterSet>("GlobalMuonTrackMatcher");
36  theTrackMatcher = new GlobalMuonTrackMatcher(trackMatcherPSet,theService);
37 
38  theTkTrackToken = iC.consumes<reco::TrackCollection>(par.getParameter<InputTag>("TkTrackCollectionLabel"));
39 
40  theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
41  theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
42  thePropagatorName = par.getParameter<string>("Propagator");
43  category_ = "Muon|RecoMuon|CosmicMuon|GlobalCosmicMuonTrajectoryBuilder";
44 
45 }
46 
47 //
48 // destructor
49 //
50 
52 
53  if (theSmoother) delete theSmoother;
54  if (theTrackMatcher) delete theTrackMatcher;
55 }
56 
57 //
58 // set Event
59 //
61  event.getByToken(theTkTrackToken,theTrackerTracks);
62 
63 // edm::Handle<std::vector<Trajectory> > handleTrackerTrajs;
64 // if ( event.getByLabel(theTkTrackLabel,handleTrackerTrajs) && handleTrackerTrajs.isValid() ) {
65 // tkTrajsAvailable = true;
66 // allTrackerTrajs = &*handleTrackerTrajs;
67 // LogInfo("GlobalCosmicMuonTrajectoryBuilder")
68 // << "Tk Trajectories Found! " << endl;
69 // } else {
70 // LogInfo("GlobalCosmicMuonTrajectoryBuilder")
71 // << "No Tk Trajectories Found! " << endl;
72 // tkTrajsAvailable = false;
73 // }
74 
77 
78 }
79 
80 //
81 // reconstruct trajectories
82 //
85 
86  if (!theTrackerTracks.isValid()) {
87  LogTrace(category_)<< "Tracker Track collection is invalid!!!";
88  return result;
89  }
90 
91  LogTrace(category_) <<"Found "<<theTrackerTracks->size()<<" tracker Tracks";
92  if (theTrackerTracks->empty()) return result;
93 
94  vector<TrackCand> matched = match(muCand, theTrackerTracks);
95 
96  LogTrace(category_) <<"TrackMatcher found " << matched.size() << "tracker tracks matched";
97 
98  if ( matched.empty()) return result;
99  reco::TrackRef tkTrack = matched.front().second;
100 
101  if ( tkTrack.isNull() ) return result;
102  reco::TrackRef muTrack = muCand.second;
103 
104  ConstRecHitContainer muRecHits;
105 
106  if (muCand.first == 0 || !muCand.first->isValid()) {
107  muRecHits = getTransientRecHits(*muTrack);
108  } else {
109  muRecHits = muCand.first->recHits();
110  }
111 
112  LogTrace(category_)<<"mu RecHits: "<<muRecHits.size();
113 
114  ConstRecHitContainer tkRecHits = getTransientRecHits(*tkTrack);
115 
116 // if ( !tkTrajsAvailable ) {
117 // tkRecHits = getTransientRecHits(*tkTrack);
118 // } else {
119 // tkRecHits = allTrackerTrajs->front().recHits();
120 // }
121 
122  ConstRecHitContainer hits; //= tkRecHits;
123  LogTrace(category_)<<"tk RecHits: "<<tkRecHits.size();
124 
125 // hits.insert(hits.end(), muRecHits.begin(), muRecHits.end());
126 // stable_sort(hits.begin(), hits.end(), DecreasingGlobalY());
127 
128  sortHits(hits, muRecHits, tkRecHits);
129 
130 // LogTrace(category_)<< "Used RecHits after sort: "<<hits.size()<<endl;;
131 // LogTrace(category_) <<utilities()->print(hits)<<endl;
132 // LogTrace(category_) << "== End of Used RecHits == "<<endl;
133 
134 
135 
136  TrajectoryStateOnSurface muonState1 = trajectoryStateTransform::innerStateOnSurface(*muTrack, *theService->trackingGeometry(), &*theService->magneticField());
137  TrajectoryStateOnSurface tkState1 = trajectoryStateTransform::innerStateOnSurface(*tkTrack, *theService->trackingGeometry(), &*theService->magneticField());
138 
139  TrajectoryStateOnSurface muonState2 = trajectoryStateTransform::outerStateOnSurface(*muTrack, *theService->trackingGeometry(), &*theService->magneticField());
140  TrajectoryStateOnSurface tkState2 = trajectoryStateTransform::outerStateOnSurface(*tkTrack, *theService->trackingGeometry(), &*theService->magneticField());
141 
142  TrajectoryStateOnSurface firstState1 =
143  ( muonState1.globalPosition().y() > tkState1.globalPosition().y() )? muonState1 : tkState1;
144  TrajectoryStateOnSurface firstState2 =
145  ( muonState2.globalPosition().y() > tkState2.globalPosition().y() )? muonState2 : tkState2;
146 
147  TrajectoryStateOnSurface firstState =
148  ( firstState1.globalPosition().y() > firstState2.globalPosition().y() )? firstState1 : firstState2;
149 
151  if(hits.size()>0){
152  front=hits.front()->globalPosition();
153  back=hits.back()->globalPosition();
154  if ( (front.perp()<130 && fabs(front.z())<300)|| (back.perp() <130 && fabs(back.z())<300)){
155  if (hits.front()->globalPosition().perp()>hits.back()->globalPosition().perp()) reverse(hits.begin(), hits.end());
156  tkState1 = trajectoryStateTransform::innerStateOnSurface(*tkTrack, *theService->trackingGeometry(), &*theService->magneticField());
157  tkState2 = trajectoryStateTransform::outerStateOnSurface(*tkTrack, *theService->trackingGeometry(), &*theService->magneticField());
158  firstState =( tkState1.globalPosition().perp() < tkState2.globalPosition().perp() )? tkState1 : tkState2;
159  }
160  }
161  if (!firstState.isValid()) return result;
162  LogTrace(category_) <<"firstTSOS pos: "<<firstState.globalPosition()<<"mom: "<<firstState.globalMomentum();
163 
164  // begin refitting
165 
166  TrajectorySeed seed;
167  vector<Trajectory> refitted = theSmoother->trajectories(seed,hits,firstState);
168 
169  if ( refitted.empty() ) {
170  LogTrace(category_)<<"smoothing trajectories fail";
171  refitted = theSmoother->fit(seed,hits,firstState); //FIXME
172  }
173 
174  if (refitted.empty()) {
175  LogTrace(category_)<<"refit fail";
176  return result;
177  }
178 
179  Trajectory* myTraj = new Trajectory(refitted.front());
180 
181  const std::vector<TrajectoryMeasurement>& mytms = myTraj->measurements();
182  LogTrace(category_)<<"measurements in final trajectory "<<mytms.size();
183  LogTrace(category_) <<"Orignally there are "<<tkTrack->found()<<" tk rhs and "<<muTrack->found()<<" mu rhs.";
184 
185  if ( mytms.size() <= tkTrack->found() ) {
186  LogTrace(category_)<<"insufficient measurements. skip... ";
187  return result;
188  }
189 
190  MuonCandidate* myCand = new MuonCandidate(myTraj,muTrack,tkTrack);
191  result.push_back(myCand);
192  LogTrace(category_)<<"final global cosmic muon: ";
193  for (std::vector<TrajectoryMeasurement>::const_iterator itm = mytms.begin();
194  itm != mytms.end(); ++itm ) {
195  LogTrace(category_)<<"updated pos "<<itm->updatedState().globalPosition()
196  <<"mom "<<itm->updatedState().globalMomentum();
197  }
198  return result;
199 }
200 
202 
203  if ( tkHits.empty() ) {
204  LogTrace(category_) << "No valid tracker hits";
205  return;
206  }
207  if ( muonHits.empty() ) {
208  LogTrace(category_) << "No valid muon hits";
209  return;
210  }
211 
212  ConstRecHitContainer::const_iterator frontTkHit = tkHits.begin();
213  ConstRecHitContainer::const_iterator backTkHit = tkHits.end() - 1;
214  while ( !(*frontTkHit)->isValid() && frontTkHit != backTkHit) {frontTkHit++;}
215  while ( !(*backTkHit)->isValid() && backTkHit != frontTkHit) {backTkHit--;}
216 
217  ConstRecHitContainer::const_iterator frontMuHit = muonHits.begin();
218  ConstRecHitContainer::const_iterator backMuHit = muonHits.end() - 1;
219  while ( !(*frontMuHit)->isValid() && frontMuHit != backMuHit) {frontMuHit++;}
220  while ( !(*backMuHit)->isValid() && backMuHit != frontMuHit) {backMuHit--;}
221 
222  if ( frontTkHit == backTkHit ) {
223  LogTrace(category_) << "No valid tracker hits";
224  return;
225  }
226  if ( frontMuHit == backMuHit ) {
227  LogTrace(category_) << "No valid muon hits";
228  return;
229  }
230 
231  GlobalPoint frontTkPos = (*frontTkHit)->globalPosition();
232  GlobalPoint backTkPos = (*backTkHit)->globalPosition();
233 
234  GlobalPoint frontMuPos = (*frontMuHit)->globalPosition();
235  GlobalPoint backMuPos = (*backMuHit)->globalPosition();
236 
237  //sort hits going from higher to lower positions
238  if ( frontTkPos.y() < backTkPos.y() ) {//check if tk hits order same direction
239  reverse(tkHits.begin(), tkHits.end());
240  }
241 
242  if ( frontMuPos.y() < backMuPos.y() ) {
243  reverse(muonHits.begin(), muonHits.end());
244  }
245 
246 // LogTrace(category_)<< "tkHits after sort: "<<tkHits.size()<<endl;;
247 // LogTrace(category_) <<utilities()->print(tkHits)<<endl;
248 // LogTrace(category_) << "== End of tkHits == "<<endl;
249 
250 // LogTrace(category_)<< "muonHits after sort: "<<muonHits.size()<<endl;;
251 // LogTrace(category_) <<utilities()->print(muonHits)<<endl;
252 // LogTrace(category_)<< "== End of muonHits == "<<endl;
253 
254  //separate muon hits into 2 different hemisphere
255  ConstRecHitContainer::iterator middlepoint = muonHits.begin();
256  bool insertInMiddle = false;
257 
258  for (ConstRecHitContainer::iterator ihit = muonHits.begin();
259  ihit != muonHits.end() - 1; ihit++ ) {
260  GlobalPoint ipos = (*ihit)->globalPosition();
261  GlobalPoint nextpos = (*(ihit+1))->globalPosition();
262  if ( (ipos-nextpos).mag() < 100.0 ) continue;
263 
264  GlobalPoint middle((ipos.x()+nextpos.x())/2, (ipos.y()+nextpos.y())/2, (ipos.z()+nextpos.z())/2);
265  LogTrace(category_)<<"ipos "<<ipos<<"nextpos"<<nextpos<<" middle "<<middle<<endl;
266  if ( (middle.perp() < ipos.perp()) && (middle.perp() < nextpos.perp() ) ) {
267  LogTrace(category_)<<"found middlepoint"<<endl;
268  middlepoint = ihit;
269  insertInMiddle = true;
270  break;
271  }
272  }
273 
274  //insert track hits in correct order
275  if ( insertInMiddle ) { //if tk hits should be sandwich
276  GlobalPoint jointpointpos = (*middlepoint)->globalPosition();
277  LogTrace(category_)<<"jointpoint "<<jointpointpos<<endl;
278  if ((frontTkPos - jointpointpos).mag() > (backTkPos - jointpointpos).mag() ) {//check if tk hits order same direction
279  reverse(tkHits.begin(), tkHits.end());
280  }
281  muonHits.insert(middlepoint+1, tkHits.begin(), tkHits.end());
282  hits = muonHits;
283  } else { // append at one end
284  if ( frontTkPos.y() < frontMuPos.y() ) { //insert at the end
285  LogTrace(category_)<<"insert at the end "<<frontTkPos << frontMuPos <<endl;
286 
287  hits = muonHits;
288  hits.insert(hits.end(), tkHits.begin(), tkHits.end());
289  } else { //insert at the beginning
290  LogTrace(category_)<<"insert at the beginning "<<frontTkPos << frontMuPos <<endl;
291  hits = tkHits;
292  hits.insert(hits.end(), muonHits.begin(), muonHits.end());
293  }
294  }
295 }
296 
297 
300 
302 
303 
304 
305  TrajectoryStateOnSurface currTsos = trajectoryStateTransform::innerStateOnSurface(track, *theService->trackingGeometry(), &*theService->magneticField());
306  for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit) {
307  if((*hit)->isValid()) {
308  DetId recoid = (*hit)->geographicalId();
309  if ( recoid.det() == DetId::Tracker ) {
311  TrajectoryStateOnSurface predTsos = theService->propagator(thePropagatorName)->propagate(currTsos, theService->trackingGeometry()->idToDet(recoid)->surface());
312  LogTrace(category_)<<"predtsos "<<predTsos.isValid();
313  if ( predTsos.isValid() ) {
314  currTsos = predTsos;
315  TransientTrackingRecHit::RecHitPointer preciseHit = ttrhit->clone(currTsos);
316  result.push_back(preciseHit);
317  }
318  } else if ( recoid.det() == DetId::Muon ) {
319  result.push_back(theMuonRecHitBuilder->build(&**hit));
320  }
321  }
322  }
323  return result;
324 }
325 
326 std::vector<GlobalCosmicMuonTrajectoryBuilder::TrackCand> GlobalCosmicMuonTrajectoryBuilder::match(const TrackCand& mu, const edm::Handle<reco::TrackCollection>& tktracks) {
327 
328  std::vector<TrackCand> result;
329 
330 
331  TrajectoryStateOnSurface innerTsos =trajectoryStateTransform::innerStateOnSurface(*(mu.second), *theService->trackingGeometry(), &*theService->magneticField());
332  TrajectoryStateOnSurface outerTsos = trajectoryStateTransform::outerStateOnSurface(*(mu.second), *theService->trackingGeometry(), &*theService->magneticField());
333  //build tracker TrackCands and pick the best match if size greater than 2
334  vector<TrackCand> tkTrackCands;
337  TrackCand tkCand = TrackCand((Trajectory*)(0),tkTrack);
338  tkTrackCands.push_back(tkCand);
339  LogTrace(category_) << "chisq is " << theTrackMatcher->match(mu,tkCand,0,0);
340  LogTrace(category_) << "d is " << theTrackMatcher->match(mu,tkCand,1,0);
341  LogTrace(category_) << "r_pos is " << theTrackMatcher->match(mu,tkCand,2,0);
342  }
343 
344  // now if only 1 tracker tracks, return it
345  if (tkTrackCands.size() <= 1 ) {
346  return tkTrackCands;
347  }
348 
349  // if there're many tracker tracks
350 
351  // if muon is only on one side
352  GlobalPoint innerPos = innerTsos.globalPosition();
353  GlobalPoint outerPos = outerTsos.globalPosition();
354 
355  if ( ( innerPos.basicVector().dot( innerTsos.globalMomentum().basicVector() ) *
356  outerPos.basicVector().dot(outerTsos.globalMomentum().basicVector() ) > 0 ) ) {
357 
358  GlobalPoint geoInnerPos = (innerPos.mag() < outerPos.mag()) ? innerPos : outerPos;
359  LogTrace(category_) <<"geoInnerPos Mu "<<geoInnerPos<<endl;
360 
361  // if there're tracker tracks totally on the other half
362  // and there're tracker tracks on the same half
363  // remove the tracks on the other half
364  for(vector<TrackCand>::const_iterator itkCand = tkTrackCands.begin(); itkCand != tkTrackCands.end(); ++itkCand) {
365 
366  reco::TrackRef tkTrack = itkCand->second;
367 
368  GlobalPoint tkInnerPos(tkTrack->innerPosition().x(), tkTrack->innerPosition().y(), tkTrack->innerPosition().z());
369  GlobalPoint tkOuterPos(tkTrack->outerPosition().x(), tkTrack->outerPosition().y(), tkTrack->outerPosition().z());
370  LogTrace(category_) <<"tkTrack "<<tkInnerPos<<" "<<tkOuterPos<<endl;
371 
372  float closetDistance11 = (geoInnerPos - tkInnerPos).mag() ;
373  float closetDistance12 = (geoInnerPos - tkOuterPos).mag() ;
374  float closetDistance1 = (closetDistance11 < closetDistance12) ? closetDistance11 : closetDistance12;
375  LogTrace(category_) <<"closetDistance1 "<<closetDistance1<<endl;
376 
377  if (true || !isTraversing(*tkTrack) ) {
378  bool keep = true;
379  for(vector<TrackCand>::const_iterator itkCand2 = tkTrackCands.begin(); itkCand2 != tkTrackCands.end(); ++itkCand2) {
380  if (itkCand2 == itkCand ) continue;
381  reco::TrackRef tkTrack2 = itkCand2->second;
382 
383  GlobalPoint tkInnerPos2(tkTrack2->innerPosition().x(), tkTrack2->innerPosition().y(), tkTrack2->innerPosition().z());
384  GlobalPoint tkOuterPos2(tkTrack2->outerPosition().x(), tkTrack2->outerPosition().y(), tkTrack2->outerPosition().z());
385  LogTrace(category_) <<"tkTrack2 "<< tkInnerPos2 <<" "<<tkOuterPos2 <<endl;
386 
387  float farthestDistance21 = (geoInnerPos - tkInnerPos2).mag() ;
388  float farthestDistance22 = (geoInnerPos - tkOuterPos2).mag() ;
389  float farthestDistance2 = (farthestDistance21 > farthestDistance22) ? farthestDistance21 : farthestDistance22;
390  LogTrace(category_) <<"farthestDistance2 "<<farthestDistance2<<endl;
391 
392  if (closetDistance1 > farthestDistance2 - 1e-3) {
393  keep = false;
394  break;
395  }
396  }
397  if (keep) result.push_back(*itkCand);
398  else LogTrace(category_) <<"The Track is on different hemisphere"<<endl;
399  } else {
400  result.push_back(*itkCand);
401  }
402  }
403  if ( result.empty() ) {
404  //if all tk tracks on the other side, still keep them
405  result = tkTrackCands;
406  }
407  } else { // muon is traversing
408  result = tkTrackCands;
409  }
410 
411  // match muCand to tkTrackCands
412  vector<TrackCand> matched_trackerTracks = theTrackMatcher->match(mu, result);
413 
414  LogTrace(category_) <<"TrackMatcher found " << matched_trackerTracks.size() << "tracker tracks matched";
415 
416  //now pick the best matched one
417  if( matched_trackerTracks.size() < 2 ) {
418  return matched_trackerTracks;
419  } else {
420  // in case of more than 1 tkTrack,
421  // select the best-one based on distance (matchOption==1)
422  // at innermost Mu hit surface. (surfaceOption == 0)
423  result.clear();
424  TrackCand bestMatch;
425 
426  double quality = 1e6;
427  double max_quality = 1e6;
428  for( vector<TrackCand>::const_iterator iter = matched_trackerTracks.begin(); iter != matched_trackerTracks.end(); iter++) {
429  quality = theTrackMatcher->match(mu,*iter, 1, 0);
430  LogTrace(category_) <<" quality of tracker track is " << quality;
431  if( quality < max_quality ) {
432  max_quality=quality;
433  bestMatch = (*iter);
434  }
435  }
436  LogTrace(category_) <<" Picked tracker track with quality " << max_quality;
437  result.push_back(bestMatch);
438  return result;
439  }
440 }
441 
442 
444 
446  for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit) {
447  if((*hit)->isValid()) {
448  firstValid = hit;
449  break;
450  }
451  }
452 
453  trackingRecHit_iterator lastValid;
454  for (trackingRecHit_iterator hit = track.recHitsEnd() - 1; hit != track.recHitsBegin() - 1; --hit) {
455  if((*hit)->isValid()) {
456  lastValid = hit;
457  break;
458  }
459  }
460 
461  GlobalPoint posFirst = theService->trackingGeometry()->idToDet((*firstValid)->geographicalId())->position();
462 
463  GlobalPoint posLast = theService->trackingGeometry()->idToDet((*lastValid)->geographicalId() )->position();
464 
465  GlobalPoint middle((posFirst.x()+posLast.x())/2, (posFirst.y()+posLast.y())/2, (posFirst.z()+posLast.z())/2);
466 
467  if ( (middle.mag() < posFirst.mag()) && (middle.mag() < posLast.mag() ) ) {
468  return true;
469  }
470  return false;
471 
472 }
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
T perp() const
Definition: PV3DBase.h:72
edm::ESHandle< TransientTrackingRecHitBuilder > theTrackerRecHitBuilder
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field)
edm::EDGetTokenT< reco::TrackCollection > theTkTrackToken
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
edm::ESHandle< TransientTrackingRecHitBuilder > theMuonRecHitBuilder
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:10
T y() const
Definition: PV3DBase.h:63
GlobalPoint globalPosition() const
std::vector< Trajectory * > trajectories(const TrajectorySeed &)
dummy implementation, unused in this class
uint16_t size_type
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
GlobalCosmicMuonTrajectoryBuilder(const edm::ParameterSet &, const MuonServiceProxy *service, edm::ConsumesCollector &iC)
Constructor.
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
DataContainer const & measurements() const
Definition: Trajectory.h:215
const int keep
ConstRecHitContainer getTransientRecHits(const reco::Track &) const
bool isNull() const
Checks for null.
Definition: Ref.h:247
T mag() const
Definition: PV3DBase.h:67
std::pair< const Trajectory *, reco::TrackRef > TrackCand
bool isTraversing(const reco::Track &tk) const
T z() const
Definition: PV3DBase.h:64
tuple result
Definition: query.py:137
const int mu
Definition: Constants.h:22
void sortHits(ConstRecHitContainer &, ConstRecHitContainer &, ConstRecHitContainer &)
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:62
std::vector< MuonCandidate * > CandidateContainer
Definition: MuonCandidate.h:20
double match(const TrackCand &sta, const TrackCand &track, int matchOption=0, int surfaceOption=1) 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
bool isValid() const
Definition: HandleBase.h:76
#define LogTrace(id)
virtual TrajectoryContainer trajectories(const Trajectory &traj) const
std::vector< ConstRecHitPointer > ConstRecHitContainer
Definition: DetId.h:18
std::vector< Trajectory > fit(const Trajectory &) const
TrajectoryStateOnSurface outerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field)
std::vector< TrackCand > match(const TrackCand &, const edm::Handle< reco::TrackCollection > &)
check if tk and muon Tracks are matched
GlobalVector globalMomentum() const
Detector det() const
get the detector field from this detid
Definition: DetId.h:35
T x() const
Definition: PV3DBase.h:62
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:56
edm::Handle< reco::TrackCollection > theTrackerTracks
T dot(const Basic3DVector &rh) const
Scalar product, or &quot;dot&quot; product, with a vector of same type.
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:64