CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GlobalTrajectoryBuilderBase.cc
Go to the documentation of this file.
1 
27 
28 //---------------
29 // C++ Headers --
30 //---------------
31 
32 #include <iostream>
33 #include <algorithm>
34 
35 //-------------------------------
36 // Collaborating Class Headers --
37 //-------------------------------
38 
42 
49 
51 
56 
61 
63 
70 
77 
80 
84 
85 using namespace std;
86 using namespace edm;
87 
88 //----------------
89 // Constructors --
90 //----------------
92  const MuonServiceProxy* service) :
93  theTrackMatcher(0),theLayerMeasurements(0),theTrackTransformer(0),theRegionBuilder(0), theService(service),theGlbRefitter(0) {
94 
95  theCategory = par.getUntrackedParameter<string>("Category", "Muon|RecoMuon|GlobalMuon|GlobalTrajectoryBuilderBase");
96 
97 
98  ParameterSet trackMatcherPSet = par.getParameter<ParameterSet>("GlobalMuonTrackMatcher");
99  theTrackMatcher = new GlobalMuonTrackMatcher(trackMatcherPSet,theService);
100 
101  theTrackerPropagatorName = par.getParameter<string>("TrackerPropagator");
102 
103  ParameterSet trackTransformerPSet = par.getParameter<ParameterSet>("TrackTransformer");
104  theTrackTransformer = new TrackTransformer(trackTransformerPSet);
105 
106  ParameterSet regionBuilderPSet = par.getParameter<ParameterSet>("MuonTrackingRegionBuilder");
107 
108  theRegionBuilder = new MuonTrackingRegionBuilder(regionBuilderPSet,theService);
109 
110  // TrackRefitter parameters
111  ParameterSet refitterParameters = par.getParameter<ParameterSet>("GlbRefitterParameters");
112  theGlbRefitter = new GlobalMuonRefitter(refitterParameters, theService);
113 
114  theMuonHitsOption = refitterParameters.getParameter<int>("MuonHitsOption");
115 
116  theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
117  theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
118 
119  theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
120 
121  theTECxScale = par.getParameter<double>("ScaleTECxFactor");
122  theTECyScale = par.getParameter<double>("ScaleTECyFactor");
123  thePtCut = par.getParameter<double>("PtCut");
124  thePCut = par.getParameter<double>("PCut");
125 
126  theCacheId_TRH = 0;
127 
128 }
129 
130 
131 //--------------
132 // Destructor --
133 //--------------
135 
136  if (theTrackMatcher) delete theTrackMatcher;
139  if (theGlbRefitter) delete theGlbRefitter;
140 }
141 
142 
143 //
144 // set Event
145 //
147 
148  theEvent = &event;
149 
151  theRegionBuilder->setEvent(event);
152 
153  theGlbRefitter->setEvent(event);
154  theGlbRefitter->setServices(theService->eventSetup());
155 
156  unsigned long long newCacheId_TRH = theService->eventSetup().get<TransientRecHitRecord>().cacheIdentifier();
157  if ( newCacheId_TRH != theCacheId_TRH ) {
158  LogDebug(theCategory) << "TransientRecHitRecord changed!";
159  theCacheId_TRH = newCacheId_TRH;
162  }
163 
164  //Retrieve tracker topology from geometry
166  theService->eventSetup().get<IdealGeometryRecord>().get(tTopoHand);
167  tTopo_=tTopoHand.product();
168 
169 }
170 
171 
172 //
173 // build a combined tracker-muon trajectory
174 //
177  MuonCandidate::CandidateContainer& tkTrajs ) const {
178 
179  LogTrace(theCategory) << " Begin Build" << endl;
180 
181  // tracker trajectory should be built and refit before this point
182  if ( tkTrajs.empty() ) return CandidateContainer();
183 
184  // add muon hits and refit/smooth trajectories
185  CandidateContainer refittedResult;
186  ConstRecHitContainer muonRecHits = getTransientRecHits(*(staCand.second));
187 
188  // check order of muon measurements
189  if ( (muonRecHits.size() > 1) &&
190  ( muonRecHits.front()->globalPosition().mag() >
191  muonRecHits.back()->globalPosition().mag() ) ) {
192  LogTrace(theCategory)<< " reverse order: ";
193  }
194 
195  for ( CandidateContainer::const_iterator it = tkTrajs.begin(); it != tkTrajs.end(); it++ ) {
196 
197  // cut on tracks with low momenta
198  LogTrace(theCategory)<< " Track p and pT " << (*it)->trackerTrack()->p() << " " << (*it)->trackerTrack()->pt();
199  if( (*it)->trackerTrack()->p() < thePCut || (*it)->trackerTrack()->pt() < thePtCut ) continue;
200 
201  ConstRecHitContainer trackerRecHits;
202  if ((*it)->trackerTrack().isNonnull()) {
203  trackerRecHits = getTransientRecHits(*(*it)->trackerTrack());
204  } else {
205  LogDebug(theCategory)<<" NEED HITS FROM TRAJ";
206  //trackerRecHits = (*it)->trackerTrajectory()->recHits();
207  }
208 
209  // check for single TEC RecHits in trajectories in the overalp region
210  if ( fabs((*it)->trackerTrack()->eta()) > 0.95 && fabs((*it)->trackerTrack()->eta()) < 1.15 && (*it)->trackerTrack()->pt() < 60 ) {
211  if ( theTECxScale < 0 || theTECyScale < 0 )
212  trackerRecHits = selectTrackerHits(trackerRecHits);
213  else
214  fixTEC(trackerRecHits,theTECxScale,theTECyScale);
215  }
216 
217  RefitDirection recHitDir = checkRecHitsOrdering(trackerRecHits);
218  if ( recHitDir == outToIn ) reverse(trackerRecHits.begin(),trackerRecHits.end());
219 
220  reco::TransientTrack tTT((*it)->trackerTrack(),&*theService->magneticField(),theService->trackingGeometry());
221  TrajectoryStateOnSurface innerTsos = tTT.innermostMeasurementState();
222 
224  if((*it)->trackerTrack()->seedRef().isAvailable()) tmpSeed = (*it)->trackerTrack()->seedRef();
225 
226  if ( !innerTsos.isValid() ) {
227  LogTrace(theCategory) << " inner Trajectory State is invalid. ";
228  continue;
229  }
230 
231  innerTsos.rescaleError(100.);
232 
233  TC refitted0,refitted1;
234  MuonCandidate* finalTrajectory = 0;
235  Trajectory *tkTrajectory = 0;
236 
237  // tracker only track
238  if ( ! ((*it)->trackerTrajectory() && (*it)->trackerTrajectory()->isValid()) ) {
239  refitted0 = theTrackTransformer->transform((*it)->trackerTrack()) ;
240  if (!refitted0.empty()) tkTrajectory = new Trajectory(*(refitted0.begin()));
241  else LogWarning(theCategory)<< " Failed to load tracker track trajectory";
242  } else tkTrajectory = (*it)->trackerTrajectory();
243  if (tkTrajectory) tkTrajectory->setSeedRef(tmpSeed);
244 
245  // full track with all muon hits using theGlbRefitter
246  ConstRecHitContainer allRecHits = trackerRecHits;
247  allRecHits.insert(allRecHits.end(), muonRecHits.begin(),muonRecHits.end());
248  refitted1 = theGlbRefitter->refit( *(*it)->trackerTrack(), tTT, allRecHits,theMuonHitsOption, tTopo_);
249  LogTrace(theCategory)<<" This track-sta refitted to " << refitted1.size() << " trajectories";
250 
251  Trajectory *glbTrajectory1 = 0;
252  if (!refitted1.empty()) glbTrajectory1 = new Trajectory(*(refitted1.begin()));
253  else LogDebug(theCategory)<< " Failed to load global track trajectory 1";
254  if (glbTrajectory1) glbTrajectory1->setSeedRef(tmpSeed);
255 
256  finalTrajectory = 0;
257  if(glbTrajectory1 && tkTrajectory) finalTrajectory = new MuonCandidate(glbTrajectory1, (*it)->muonTrack(), (*it)->trackerTrack(),
258  tkTrajectory? new Trajectory(*tkTrajectory) : 0);
259 
260  if ( finalTrajectory )
261  refittedResult.push_back(finalTrajectory);
262 
263  if(tkTrajectory) delete tkTrajectory;
264  }
265 
266  // choose the best global fit for this Standalone Muon based on the track probability
267  CandidateContainer selectedResult;
268  MuonCandidate* tmpCand = 0;
269  if ( refittedResult.size() > 0 ) tmpCand = *(refittedResult.begin());
270  double minProb = 9999;
271 
272  for (CandidateContainer::const_iterator iter=refittedResult.begin(); iter != refittedResult.end(); iter++) {
273  double prob = trackProbability(*(*iter)->trajectory());
274  LogTrace(theCategory)<<" refitted-track-sta with pT " << (*iter)->trackerTrack()->pt() << " has probability " << prob;
275 
276  if (prob < minProb) {
277  minProb = prob;
278  tmpCand = (*iter);
279  }
280  }
281 
282  if ( tmpCand ) selectedResult.push_back(new MuonCandidate(new Trajectory(*(tmpCand->trajectory())), tmpCand->muonTrack(), tmpCand->trackerTrack(),
283  (tmpCand->trackerTrajectory())? new Trajectory( *(tmpCand->trackerTrajectory()) ):0 ) );
284 
285  for (CandidateContainer::const_iterator it = refittedResult.begin(); it != refittedResult.end(); ++it) {
286  if ( (*it)->trajectory() ) delete (*it)->trajectory();
287  if ( (*it)->trackerTrajectory() ) delete (*it)->trackerTrajectory();
288  if ( *it ) delete (*it);
289  }
290  refittedResult.clear();
291 
292  return selectedResult;
293 
294 }
295 
296 
297 //
298 // select tracker tracks within a region of interest
299 //
300 vector<GlobalTrajectoryBuilderBase::TrackCand>
302  const vector<TrackCand>& tkTs) {
303 
304  // define eta-phi region
305  RectangularEtaPhiTrackingRegion regionOfInterest = defineRegionOfInterest(staCand.second);
306 
307  // get region's etaRange and phiMargin
308  //UNUSED: PixelRecoRange<float> etaRange = regionOfInterest.etaRange();
309  //UNUSED: TkTrackingRegionsMargin<float> phiMargin = regionOfInterest.phiMargin();
310 
311  vector<TrackCand> result;
312 
313  double deltaR_max = 1.0;
314 
315  for ( vector<TrackCand>::const_iterator is = tkTs.begin(); is != tkTs.end(); ++is ) {
316  // check if each trackCand is in region of interest
317 // bool inEtaRange = etaRange.inside(is->second->eta());
318 // bool inPhiRange = (fabs(Geom::Phi<float>(is->second->phi()) - Geom::Phi<float>(regionOfInterest.direction().phi())) < phiMargin.right() ) ? true : false ;
319 
320  double deltaR_tmp = deltaR(static_cast<double>(regionOfInterest.direction().eta()),
321  static_cast<double>(regionOfInterest.direction().phi()),
322  is->second->eta(), is->second->phi());
323 
324  // for each trackCand in region, add trajectory and add to result
325  //if ( inEtaRange && inPhiRange ) {
326  if (deltaR_tmp < deltaR_max) {
327  TrackCand tmpCand = TrackCand(*is);
328  result.push_back(tmpCand);
329  }
330  }
331 
332  return result;
333 
334 }
335 
336 
337 //
338 // define a region of interest within the tracker
339 //
342 
344 
345  TkTrackingRegionsMargin<float> etaMargin(fabs(region1->etaRange().min() - region1->etaRange().mean()),
346  fabs(region1->etaRange().max() - region1->etaRange().mean()));
347 
348  RectangularEtaPhiTrackingRegion region2(region1->direction(),
349  region1->origin(),
350  region1->ptMin(),
351  region1->originRBound(),
352  region1->originZBound(),
353  etaMargin,
354  region1->phiMargin());
355 
356  delete region1;
357  return region2;
358 
359 }
360 
361 
362 //
363 // calculate the tail probability (-ln(P)) of a fit
364 //
365 double
367 
368  if ( track.ndof() > 0 && track.chiSquared() > 0 ) {
369  return -LnChiSquaredProbability(track.chiSquared(), track.ndof());
370  } else {
371  return 0.0;
372  }
373 
374 }
375 
376 
377 //
378 // print RecHits
379 //
381 
382  LogTrace(theCategory) << "Used RecHits: " << hits.size();
383  for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
384  if ( !(*ir)->isValid() ) {
385  LogTrace(theCategory) << "invalid RecHit";
386  continue;
387  }
388 
389  const GlobalPoint& pos = (*ir)->globalPosition();
390 
392  << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y())
393  << " z = " << pos.z()
394  << " dimension = " << (*ir)->dimension()
395  << " " << (*ir)->det()->geographicalId().det()
396  << " " << (*ir)->det()->subDetector();
397 
398  }
399 
400 }
401 
402 //
403 // check order of RechIts on a trajectory
404 //
407 
408  if ( !recHits.empty() ) {
409  ConstRecHitContainer::const_iterator frontHit = recHits.begin();
410  ConstRecHitContainer::const_iterator backHit = recHits.end() - 1;
411  while ( !(*frontHit)->isValid() && frontHit != backHit ) {frontHit++;}
412  while ( !(*backHit)->isValid() && backHit != frontHit ) {backHit--;}
413 
414  double rFirst = (*frontHit)->globalPosition().mag();
415  double rLast = (*backHit) ->globalPosition().mag();
416 
417  if ( rFirst < rLast ) return inToOut;
418  else if (rFirst > rLast) return outToIn;
419  else {
420  LogError(theCategory) << "Impossible to determine the rechits order" << endl;
421  return undetermined;
422  }
423  }
424  else {
425  LogError(theCategory) << "Impossible to determine the rechits order" << endl;
426  return undetermined;
427  }
428 }
429 
430 
431 //
432 // select trajectories with only a single TEC hit
433 //
436 
437  int nTEC(0);
438 
440  for (ConstRecHitContainer::const_iterator i = all.begin(); i != all.end(); i++) {
441  if ( !(*i)->isValid() ) continue;
442  if ( (*i)->det()->geographicalId().det() == DetId::Tracker &&
443  (*i)->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
444  nTEC++;
445  } else {
446  hits.push_back((*i).get());
447  }
448  if ( nTEC > 1 ) return all;
449  }
450 
451  return hits;
452 
453 }
454 
455 
456 //
457 // rescale errors of outermost TEC RecHit
458 //
460  double scl_x,
461  double scl_y) const {
462 
463  int nTEC(0);
464  ConstRecHitContainer::iterator lone_tec;
465 
466  for ( ConstRecHitContainer::iterator i = all.begin(); i != all.end(); i++) {
467  if ( !(*i)->isValid() ) continue;
468 
469  if ( (*i)->det()->geographicalId().det() == DetId::Tracker &&
470  (*i)->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
471  lone_tec = i;
472  nTEC++;
473 
474  if ( (i+1) != all.end() && (*(i+1))->isValid() &&
475  (*(i+1))->det()->geographicalId().det() == DetId::Tracker &&
476  (*(i+1))->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
477  nTEC++;
478  break;
479  }
480  }
481 
482  if (nTEC > 1) break;
483  }
484 
485  int hitDet = (*lone_tec)->hit()->geographicalId().det();
486  int hitSubDet = (*lone_tec)->hit()->geographicalId().subdetId();
487  if ( nTEC == 1 && (*lone_tec)->hit()->isValid() &&
488  hitDet == DetId::Tracker && hitSubDet == StripSubdetector::TEC) {
489 
490  // rescale the TEC rechit error matrix in its rotated frame
491  const SiStripRecHit2D* strip = dynamic_cast<const SiStripRecHit2D*>((*lone_tec)->hit());
492  const TSiStripRecHit2DLocalPos* Tstrip = dynamic_cast<const TSiStripRecHit2DLocalPos*>((*lone_tec).get());
493  if (strip && Tstrip->det() && Tstrip) {
494  LocalPoint pos = Tstrip->localPosition();
495  if ((*lone_tec)->detUnit()) {
496  const StripTopology* topology = dynamic_cast<const StripTopology*>(&(*lone_tec)->detUnit()->topology());
497  if (topology) {
498  // rescale the local error along/perp the strip by a factor
499  float angle = topology->stripAngle(topology->strip((*lone_tec)->hit()->localPosition()));
500  LocalError error = Tstrip->localPositionError();
501  LocalError rotError = error.rotate(angle);
502  LocalError scaledError(rotError.xx() * scl_x * scl_x, 0, rotError.yy() * scl_y * scl_y);
503  error = scaledError.rotate(-angle);
504  MuonTransientTrackingRecHit* mtt_rechit;
505  if (strip->cluster().isNonnull()) {
509  SiStripRecHit2D* st = new SiStripRecHit2D(pos,error,
510  (*lone_tec)->geographicalId().rawId(),
511  strip->cluster());
512  *lone_tec = mtt_rechit->build((*lone_tec)->det(),st);
513  }
514  else {
515  SiStripRecHit2D* st = new SiStripRecHit2D(pos,error,
516  (*lone_tec)->geographicalId().rawId(),
517  strip->cluster_regional());
518  *lone_tec = mtt_rechit->build((*lone_tec)->det(),st);
519  }
520  }
521  }
522  }
523  }
524 
525 }
526 
527 
528 //
529 // get transient RecHits
530 //
533 
535 
536 
537 
538  TrajectoryStateOnSurface currTsos = trajectoryStateTransform::innerStateOnSurface(track, *theService->trackingGeometry(), &*theService->magneticField());
539 
540  for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit) {
541  if((*hit)->isValid()) {
542  DetId recoid = (*hit)->geographicalId();
543  if ( recoid.det() == DetId::Tracker ) {
545  if (!ttrhit->hit()->hasPositionAndError()){
546  TrajectoryStateOnSurface predTsos = theService->propagator(theTrackerPropagatorName)->propagate(currTsos, theService->trackingGeometry()->idToDet(recoid)->surface());
547 
548  if ( !predTsos.isValid() ) {
549  edm::LogError("MissingTransientHit")
550  <<"Could not get a tsos on the hit surface. We will miss a tracking hit.";
551  continue;
552  }
553  currTsos = predTsos;
554  TransientTrackingRecHit::RecHitPointer preciseHit = ttrhit->clone(predTsos);
555  result.push_back(preciseHit);
556  }else{
557  result.push_back(ttrhit);
558  }
559  } else if ( recoid.det() == DetId::Muon ) {
560  if ( (*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit) {
561  LogDebug(theCategory) << "RPC Rec Hit discarded";
562  continue;
563  }
564  result.push_back(theMuonRecHitBuilder->build(&**hit));
565  }
566  }
567  }
568 
569  return result;
570 }
#define LogDebug(id)
const reco::TrackRef muonTrack() const
return muon track
Definition: MuonCandidate.h:45
RectangularEtaPhiTrackingRegion * region(const reco::TrackRef &) const
define tracking region
T getParameter(std::string const &) const
MuonCandidate::CandidateContainer CandidateContainer
void printHits(const ConstRecHitContainer &) const
print all RecHits of a trajectory
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:24
ConstRecHitContainer selectTrackerHits(const ConstRecHitContainer &) const
select tracker hits; exclude some tracker hits in the global trajectory
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
std::pair< const Trajectory *, reco::TrackRef > TrackCand
virtual float stripAngle(float strip) const =0
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field)
GlobalTrajectoryBuilderBase(const edm::ParameterSet &, const MuonServiceProxy *)
constructor with Parameter Set and MuonServiceProxy
edm::ESHandle< TransientTrackingRecHitBuilder > theMuonRecHitBuilder
float LnChiSquaredProbability(double chiSquared, double nrDOF)
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
T y() const
Definition: PV3DBase.h:63
void setServices(const edm::EventSetup &)
set the services needed by the TrackTransformer
std::vector< TrackCand > chooseRegionalTrackerTracks(const TrackCand &, const std::vector< TrackCand > &)
choose tracker tracks within region of interest
virtual float strip(const LocalPoint &) const =0
const reco::TrackRef trackerTrack() const
return tracker track
Definition: MuonCandidate.h:48
void fixTEC(ConstRecHitContainer &all, double scl_x, double scl_y) const
rescale errors of outermost TEC RecHit
double trackProbability(const Trajectory &) const
calculate chi2 probability (-ln(P))
float yy() const
Definition: LocalError.h:26
virtual ~GlobalTrajectoryBuilderBase()
destructor
T sqrt(T t)
Definition: SSEVec.h:48
Trajectory * trackerTrajectory() const
return tracker trajectory
Definition: MuonCandidate.h:51
T z() const
Definition: PV3DBase.h:64
tuple result
Definition: query.py:137
TransientTrackingRecHit::ConstRecHitContainer getTransientRecHits(const reco::Track &) const
get transient RecHits of a Track
virtual void setServices(const edm::EventSetup &)
set the services needed by the TrackTransformer
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:63
std::vector< MuonCandidate * > CandidateContainer
Definition: MuonCandidate.h:22
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
#define LogTrace(id)
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
std::vector< ConstRecHitPointer > ConstRecHitContainer
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
Definition: DetId.h:20
int ndof(bool bon=true) const
Definition: Trajectory.cc:74
GlobalMuonTrackMatcher * theTrackMatcher
T const * product() const
Definition: ESHandle.h:62
MuonTrajectoryBuilder::CandidateContainer build(const TrackCand &, MuonTrajectoryBuilder::CandidateContainer &) const
build combined trajectory from sta Track and tracker RecHits
void setSeedRef(const edm::RefToBase< TrajectorySeed > &seedRef)
Definition: Trajectory.h:310
RectangularEtaPhiTrackingRegion defineRegionOfInterest(const reco::TrackRef &) const
define region of interest with tracker
virtual std::vector< Trajectory > transform(const reco::Track &) const
Convert a reco::Track into Trajectory.
RefitDirection checkRecHitsOrdering(const ConstRecHitContainer &) const
This does nothing now.
MuonTrackingRegionBuilder * theRegionBuilder
Trajectory * trajectory() const
return trajectory
Definition: MuonCandidate.h:42
LocalError rotate(float x, float y) const
Return a new LocalError, rotated by an angle defined by the direction (x,y)
Definition: LocalError.h:39
Detector det() const
get the detector field from this detid
Definition: DetId.h:37
T x() const
Definition: PV3DBase.h:62
static RecHitPointer build(const GeomDet *geom, const TrackingRecHit *rh)
FIXME virtual ConstMuonRecHitContainer specificTransientHits() const;.
std::vector< Trajectory > refit(const reco::Track &globalTrack, const int theMuonHitsOption, const TrackerTopology *tTopo) const
build combined trajectory from sta Track and tracker RecHits
edm::ESHandle< TransientTrackingRecHitBuilder > theTrackerRecHitBuilder
double chiSquared() const
Definition: Trajectory.h:254
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:65