CMS 3D CMS Logo

GlobalTrajectoryBuilderBase.cc
Go to the documentation of this file.
1 
21 
22 //---------------
23 // C++ Headers --
24 //---------------
25 
26 #include <iostream>
27 #include <algorithm>
28 #include <limits>
29 
30 //-------------------------------
31 // Collaborating Class Headers --
32 //-------------------------------
33 
37 
42 
44 
49 
54 
61 
66 
69 
72 
73 //----------------
74 // Constructors --
75 //----------------
79  : theLayerMeasurements(nullptr),
80  theTrackTransformer(nullptr),
81  theRegionBuilder(nullptr),
82  theService(service),
83  theGlbRefitter(nullptr) {
84  theCategory =
85  par.getUntrackedParameter<std::string>("Category", "Muon|RecoMuon|GlobalMuon|GlobalTrajectoryBuilderBase");
86 
87  edm::ParameterSet trackMatcherPSet = par.getParameter<edm::ParameterSet>("GlobalMuonTrackMatcher");
88  theTrackMatcher = new GlobalMuonTrackMatcher(trackMatcherPSet, theService);
89 
90  theTrackerPropagatorName = par.getParameter<std::string>("TrackerPropagator");
91 
92  edm::ParameterSet trackTransformerPSet = par.getParameter<edm::ParameterSet>("TrackTransformer");
93  theTrackTransformer = new TrackTransformer(trackTransformerPSet, iC);
94 
95  edm::ParameterSet regionBuilderPSet = par.getParameter<edm::ParameterSet>("MuonTrackingRegionBuilder");
96 
97  theRegionBuilder = new MuonTrackingRegionBuilder(regionBuilderPSet, iC);
98 
99  // TrackRefitter parameters
100  edm::ParameterSet refitterParameters = par.getParameter<edm::ParameterSet>("GlbRefitterParameters");
101  theGlbRefitter = new GlobalMuonRefitter(refitterParameters, theService, iC);
102 
103  theMuonHitsOption = refitterParameters.getParameter<int>("MuonHitsOption");
104  theRefitFlag = refitterParameters.getParameter<bool>("RefitFlag");
105 
107  iC.esConsumes(edm::ESInputTag("", par.getParameter<std::string>("TrackerRecHitBuilder")));
108  theMuonRecHitBuilderToken = iC.esConsumes(edm::ESInputTag("", par.getParameter<std::string>("MuonRecHitBuilder")));
109  theTopoToken = iC.esConsumes();
110  theFieldToken = iC.esConsumes();
112 
113  theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
114 
115  theTECxScale = par.getParameter<double>("ScaleTECxFactor");
116  theTECyScale = par.getParameter<double>("ScaleTECyFactor");
117  thePtCut = par.getParameter<double>("PtCut");
118  thePCut = par.getParameter<double>("PCut");
119 }
120 
121 //--------------
122 // Destructor --
123 //--------------
125  if (theTrackMatcher)
126  delete theTrackMatcher;
127  if (theRegionBuilder)
128  delete theRegionBuilder;
130  delete theTrackTransformer;
131  if (theGlbRefitter)
132  delete theGlbRefitter;
133 }
134 
135 //
136 // set Event
137 //
139  theEvent = &event;
140 
143 
146 
149 
150  //Retrieve tracker topology from geometry
152 
155 }
156 
157 //
158 // build a combined tracker-muon trajectory
159 //
161  MuonCandidate::CandidateContainer& tkTrajs) const {
162  LogTrace(theCategory) << " Begin Build" << std::endl;
163 
164  // tracker trajectory should be built and refit before this point
165  if (tkTrajs.empty())
166  return CandidateContainer();
167 
168  // add muon hits and refit/smooth trajectories
169  CandidateContainer refittedResult;
170  ConstRecHitContainer muonRecHits = getTransientRecHits(*(staCand.second));
171 
172  // check order of muon measurements
173  if ((muonRecHits.size() > 1) &&
174  (muonRecHits.front()->globalPosition().mag() > muonRecHits.back()->globalPosition().mag())) {
175  LogTrace(theCategory) << " reverse order: ";
176  }
177 
178  for (auto&& it : tkTrajs) {
179  // cut on tracks with low momenta
180  LogTrace(theCategory) << " Track p and pT " << it->trackerTrack()->p() << " " << it->trackerTrack()->pt();
181  if (it->trackerTrack()->p() < thePCut || it->trackerTrack()->pt() < thePtCut)
182  continue;
183 
184  // If true we will run theGlbRefitter->refit from all hits
185  if (theRefitFlag) {
186  ConstRecHitContainer trackerRecHits;
187  if (it->trackerTrack().isNonnull()) {
188  trackerRecHits = getTransientRecHits(*it->trackerTrack());
189  } else {
190  LogDebug(theCategory) << " NEED HITS FROM TRAJ";
191  }
192 
193  // ToDo: Do we need the following ?:
194  // check for single TEC RecHits in trajectories in the overalp region
195  if (std::abs(it->trackerTrack()->eta()) > 0.95 && std::abs(it->trackerTrack()->eta()) < 1.15 &&
196  it->trackerTrack()->pt() < 60) {
197  if (theTECxScale < 0 || theTECyScale < 0)
198  trackerRecHits = selectTrackerHits(trackerRecHits);
199  else
200  fixTEC(trackerRecHits, theTECxScale, theTECyScale);
201  }
202 
203  RefitDirection recHitDir = checkRecHitsOrdering(trackerRecHits);
204  if (recHitDir == outToIn)
205  reverse(trackerRecHits.begin(), trackerRecHits.end());
206 
207  reco::TransientTrack tTT(it->trackerTrack(), &*theService->magneticField(), theService->trackingGeometry());
208  TrajectoryStateOnSurface innerTsos = tTT.innermostMeasurementState();
209 
211  if (it->trackerTrack()->seedRef().isAvailable())
212  tmpSeed = it->trackerTrack()->seedRef();
213 
214  if (!innerTsos.isValid()) {
215  LogTrace(theCategory) << " inner Trajectory State is invalid. ";
216  continue;
217  }
218 
219  innerTsos.rescaleError(100.);
220 
221  TC refitted0, refitted1;
222  std::unique_ptr<Trajectory> tkTrajectory;
223 
224  // tracker only track
225  if (!(it->trackerTrajectory() && it->trackerTrajectory()->isValid())) {
226  refitted0 = theTrackTransformer->transform(it->trackerTrack());
227  if (!refitted0.empty())
228  tkTrajectory = std::make_unique<Trajectory>(*(refitted0.begin()));
229  else
230  LogDebug(theCategory) << " Failed to load tracker track trajectory";
231  } else
232  tkTrajectory = it->releaseTrackerTrajectory();
233  if (tkTrajectory)
234  tkTrajectory->setSeedRef(tmpSeed);
235 
236  // full track with all muon hits using theGlbRefitter
237  ConstRecHitContainer allRecHits = trackerRecHits;
238  allRecHits.insert(allRecHits.end(), muonRecHits.begin(), muonRecHits.end());
239  refitted1 = theGlbRefitter->refit(*it->trackerTrack(), tTT, allRecHits, theMuonHitsOption, theTopo);
240  LogTrace(theCategory) << " This track-sta refitted to " << refitted1.size() << " trajectories";
241 
242  std::unique_ptr<Trajectory> glbTrajectory1;
243  if (!refitted1.empty())
244  glbTrajectory1 = std::make_unique<Trajectory>(*(refitted1.begin()));
245  else
246  LogDebug(theCategory) << " Failed to load global track trajectory 1";
247  if (glbTrajectory1)
248  glbTrajectory1->setSeedRef(tmpSeed);
249 
250  if (glbTrajectory1 && tkTrajectory) {
251  refittedResult.emplace_back(std::make_unique<MuonCandidate>(
252  std::move(glbTrajectory1), it->muonTrack(), it->trackerTrack(), std::move(tkTrajectory)));
253  }
254  } else {
256  if (it->trackerTrack()->seedRef().isAvailable())
257  tmpSeed = it->trackerTrack()->seedRef();
258 
259  TC refitted0;
260  std::unique_ptr<Trajectory> tkTrajectory;
261  if (!(it->trackerTrajectory() && it->trackerTrajectory()->isValid())) {
262  refitted0 = theTrackTransformer->transform(it->trackerTrack());
263  if (!refitted0.empty()) {
264  tkTrajectory = std::make_unique<Trajectory>(*(refitted0.begin()));
265  } else
266  LogDebug(theCategory) << " Failed to load tracker track trajectory";
267  } else
268  tkTrajectory = it->releaseTrackerTrajectory();
269  std::unique_ptr<Trajectory> cpy;
270  if (tkTrajectory) {
271  tkTrajectory->setSeedRef(tmpSeed);
272  cpy = std::make_unique<Trajectory>(*tkTrajectory);
273  }
274  // Creating MuonCandidate using only the tracker trajectory:
275  refittedResult.emplace_back(std::make_unique<MuonCandidate>(
276  std::move(tkTrajectory), it->muonTrack(), it->trackerTrack(), std::move(cpy)));
277  }
278  }
279 
280  // choose the best global fit for this Standalone Muon based on the track probability
281  CandidateContainer selectedResult;
282  std::unique_ptr<MuonCandidate> tmpCand;
284 
285  for (auto&& cand : refittedResult) {
286  double prob = trackProbability(*cand->trajectory());
287  LogTrace(theCategory) << " refitted-track-sta with pT " << cand->trackerTrack()->pt() << " has probability "
288  << prob;
289 
290  if (prob < minProb or not tmpCand) {
291  minProb = prob;
292  tmpCand = std::move(cand);
293  }
294  }
295 
296  if (tmpCand)
297  selectedResult.push_back(std::move(tmpCand));
298 
299  refittedResult.clear();
300 
301  return selectedResult;
302 }
303 
304 //
305 // select tracker tracks within a region of interest
306 //
307 std::vector<GlobalTrajectoryBuilderBase::TrackCand> GlobalTrajectoryBuilderBase::chooseRegionalTrackerTracks(
308  const TrackCand& staCand, const std::vector<TrackCand>& tkTs) {
309  // define eta-phi region
310  RectangularEtaPhiTrackingRegion regionOfInterest = defineRegionOfInterest(staCand.second);
311 
312  // get region's etaRange and phiMargin
313  //UNUSED: PixelRecoRange<float> etaRange = regionOfInterest.etaRange();
314  //UNUSED: TkTrackingRegionsMargin<float> phiMargin = regionOfInterest.phiMargin();
315 
316  std::vector<TrackCand> result;
317 
318  double deltaR_max = 1.0;
319 
320  for (auto&& is : tkTs) {
321  double deltaR_tmp = deltaR(static_cast<double>(regionOfInterest.direction().eta()),
322  static_cast<double>(regionOfInterest.direction().phi()),
323  is.second->eta(),
324  is.second->phi());
325 
326  // for each trackCand in region, add trajectory and add to result
327  //if ( inEtaRange && inPhiRange ) {
328  if (deltaR_tmp < deltaR_max) {
329  TrackCand tmpCand = TrackCand(is);
330  result.push_back(tmpCand);
331  }
332  }
333 
334  return result;
335 }
336 
337 //
338 // define a region of interest within the tracker
339 //
341  const reco::TrackRef& staTrack) const {
342  std::unique_ptr<RectangularEtaPhiTrackingRegion> region1 = theRegionBuilder->region(staTrack);
343 
344  TkTrackingRegionsMargin<float> etaMargin(std::abs(region1->etaRange().min() - region1->etaRange().mean()),
345  std::abs(region1->etaRange().max() - region1->etaRange().mean()));
346 
347  RectangularEtaPhiTrackingRegion region2(region1->direction(),
348  region1->origin(),
349  region1->ptMin(),
350  region1->originRBound(),
351  region1->originZBound(),
352  etaMargin,
353  region1->phiMargin(),
354  *theField,
355  theMSMaker);
356 
357  return region2;
358 }
359 
360 //
361 // calculate the tail probability (-ln(P)) of a fit
362 //
364  if (track.ndof() > 0 && track.chiSquared() > 0) {
365  return -LnChiSquaredProbability(track.chiSquared(), track.ndof());
366  } else {
367  return 0.0;
368  }
369 }
370 
371 //
372 // print RecHits
373 //
375  LogTrace(theCategory) << "Used RecHits: " << hits.size();
376  for (auto&& ir : hits) {
377  if (!ir->isValid()) {
378  LogTrace(theCategory) << "invalid RecHit";
379  continue;
380  }
381 
382  const GlobalPoint& pos = ir->globalPosition();
383 
384  LogTrace(theCategory) << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y()) << " z = " << pos.z()
385  << " dimension = " << ir->dimension() << " " << ir->det()->geographicalId().det() << " "
386  << ir->det()->subDetector();
387  }
388 }
389 
390 //
391 // check order of RechIts on a trajectory
392 //
395  if (!recHits.empty()) {
396  ConstRecHitContainer::const_iterator frontHit = recHits.begin();
397  ConstRecHitContainer::const_iterator backHit = recHits.end() - 1;
398  while (!(*frontHit)->isValid() && frontHit != backHit) {
399  frontHit++;
400  }
401  while (!(*backHit)->isValid() && backHit != frontHit) {
402  backHit--;
403  }
404 
405  double rFirst = (*frontHit)->globalPosition().mag();
406  double rLast = (*backHit)->globalPosition().mag();
407 
408  if (rFirst < rLast)
409  return inToOut;
410  else if (rFirst > rLast)
411  return outToIn;
412  else {
413  edm::LogError(theCategory) << "Impossible to determine the rechits order" << std::endl;
414  return undetermined;
415  }
416  } else {
417  edm::LogError(theCategory) << "Impossible to determine the rechits order" << std::endl;
418  return undetermined;
419  }
420 }
421 
422 //
423 // select trajectories with only a single TEC hit
424 //
426  const ConstRecHitContainer& all) const {
427  int nTEC(0);
428 
430  for (auto&& i : all) {
431  if (!i->isValid())
432  continue;
433  if (i->det()->geographicalId().det() == DetId::Tracker &&
434  i->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
435  nTEC++;
436  } else {
437  hits.push_back(i);
438  }
439  if (nTEC > 1)
440  return all;
441  }
442 
443  return hits;
444 }
445 
446 //
447 // rescale errors of outermost TEC RecHit
448 //
449 void GlobalTrajectoryBuilderBase::fixTEC(ConstRecHitContainer& all, double scl_x, double scl_y) const {
450  int nTEC(0);
451  ConstRecHitContainer::iterator lone_tec;
452 
453  for (ConstRecHitContainer::iterator i = all.begin(); i != all.end(); i++) {
454  if (!(*i)->isValid())
455  continue;
456 
457  if ((*i)->det()->geographicalId().det() == DetId::Tracker &&
458  (*i)->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
459  lone_tec = i;
460  nTEC++;
461 
462  if ((i + 1) != all.end() && (*(i + 1))->isValid() &&
463  (*(i + 1))->det()->geographicalId().det() == DetId::Tracker &&
464  (*(i + 1))->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
465  nTEC++;
466  break;
467  }
468  }
469 
470  if (nTEC > 1)
471  break;
472  }
473 
474  int hitDet = (*lone_tec)->hit()->geographicalId().det();
475  int hitSubDet = (*lone_tec)->hit()->geographicalId().subdetId();
476  if (nTEC == 1 && (*lone_tec)->hit()->isValid() && hitDet == DetId::Tracker && hitSubDet == StripSubdetector::TEC) {
477  // rescale the TEC rechit error matrix in its rotated frame
478  const SiStripRecHit2D* strip = dynamic_cast<const SiStripRecHit2D*>((*lone_tec)->hit());
479  if (strip && strip->det()) {
480  LocalPoint pos = strip->localPosition();
481  if ((*lone_tec)->detUnit()) {
482  const StripTopology* topology = dynamic_cast<const StripTopology*>(&(*lone_tec)->detUnit()->topology());
483  if (topology) {
484  // rescale the local error along/perp the strip by a factor
485  float angle = topology->stripAngle(topology->strip((*lone_tec)->hit()->localPosition()));
486  LocalError error = strip->localPositionError();
487  LocalError rotError = error.rotate(angle);
488  LocalError scaledError(rotError.xx() * scl_x * scl_x, 0, rotError.yy() * scl_y * scl_y);
489  error = scaledError.rotate(-angle);
494  SiStripRecHit2D* st = new SiStripRecHit2D(pos, error, *strip->det(), strip->cluster());
495  *lone_tec = MuonTransientTrackingRecHit::build((*lone_tec)->det(), st);
496  }
497  }
498  }
499  }
500 }
501 
503 //
504 // get transient RecHits
505 //
507  const reco::Track& track) const {
509 
512 
513  auto tkbuilder = static_cast<TkTransientTrackingRecHitBuilder const*>(theTrackerRecHitBuilder);
514  auto hitCloner = tkbuilder->cloner();
515  for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit) {
516  if ((*hit)->isValid()) {
517  DetId recoid = (*hit)->geographicalId();
518  if (recoid.det() == DetId::Tracker) {
519  if (!(*hit)->hasPositionAndError()) {
520  TrajectoryStateOnSurface predTsos =
522  ->propagate(currTsos, theService->trackingGeometry()->idToDet(recoid)->surface());
523 
524  if (!predTsos.isValid()) {
525  edm::LogError("MissingTransientHit")
526  << "Could not get a tsos on the hit surface. We will miss a tracking hit.";
527  continue;
528  }
529  currTsos = predTsos;
530  auto h = (**hit).cloneForFit(*tkbuilder->geometry()->idToDet((**hit).geographicalId()));
531  result.emplace_back(hitCloner.makeShared(h, predTsos));
532  } else {
533  result.push_back((*hit)->cloneSH());
534  }
535  } else if (recoid.det() == DetId::Muon) {
536  if ((*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit) {
537  LogDebug(theCategory) << "RPC Rec Hit discarded";
538  continue;
539  }
540  result.push_back(theMuonRecHitBuilder->build(&**hit));
541  }
542  }
543  }
544 
545  return result;
546 }
MuonTrajectoryBuilder::CandidateContainer build(const TrackCand &, MuonTrajectoryBuilder::CandidateContainer &) const
build combined trajectory from sta Track and tracker RecHits
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > theTopoToken
TransientTrackingRecHit::ConstRecHitContainer getTransientRecHits(const reco::Track &) const
get transient RecHits of a Track
static constexpr auto TEC
MuonCandidate::CandidateContainer CandidateContainer
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
edm::ESHandle< GlobalTrackingGeometry > trackingGeometry() const
get the tracking geometry
std::unique_ptr< RectangularEtaPhiTrackingRegion > region(const reco::TrackRef &) const
Define tracking region.
void setServices(const edm::EventSetup &) override
set the services needed by the TrackTransformer
edm::ESHandle< MagneticField > magneticField() const
get the magnetic field
std::pair< const Trajectory *, reco::TrackRef > TrackCand
virtual float stripAngle(float strip) const =0
def all(container)
workaround iterator generators for ROOT classes
Definition: cmstools.py:25
ConstRecHitContainer selectTrackerHits(const ConstRecHitContainer &) const
select tracker hits; exclude some tracker hits in the global trajectory
float LnChiSquaredProbability(double chiSquared, double nrDOF)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
T eta() const
Definition: PV3DBase.h:73
const TransientTrackingRecHitBuilder * theMuonRecHitBuilder
void setServices(const edm::EventSetup &)
set the services needed by the TrackTransformer
void fixTEC(ConstRecHitContainer &all, double scl_x, double scl_y) const
rescale errors of outermost TEC RecHit
edm::ESGetToken< MultipleScatteringParametrisationMaker, TrackerMultipleScatteringRecord > theMSMakerToken
std::vector< TrackCand > chooseRegionalTrackerTracks(const TrackCand &, const std::vector< TrackCand > &)
choose tracker tracks within region of interest
Log< level::Error, false > LogError
const TransientTrackingRecHitBuilder * theTrackerRecHitBuilder
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
const GeomDet * idToDet(DetId) const override
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
~GlobalTrajectoryBuilderBase() override
destructor
#define LogTrace(id)
virtual float strip(const LocalPoint &) const =0
T getUntrackedParameter(std::string const &, T const &) const
float yy() const
Definition: LocalError.h:24
double trackProbability(const Trajectory &) const
calculate chi2 probability (-ln(P))
void printHits(const ConstRecHitContainer &) const
print all RecHits of a trajectory
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > theFieldToken
T sqrt(T t)
Definition: SSEVec.h:19
virtual RecHitPointer build(const TrackingRecHit *p) const =0
build a tracking rechit from an existing rechit
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void setEvent(const edm::Event &, const edm::EventSetup &)
Pass the Event to the algo at each event.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void setEvent(const edm::Event &) override
pass the Event to the algo at each event
bool getData(T &iHolder) const
Definition: EventSetup.h:122
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
std::vector< ConstRecHitPointer > ConstRecHitContainer
GlobalTrajectoryBuilderBase(const edm::ParameterSet &, const MuonServiceProxy *, edm::ConsumesCollector &)
constructor with Parameter Set and MuonServiceProxy
const MultipleScatteringParametrisationMaker * theMSMaker
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
RectangularEtaPhiTrackingRegion defineRegionOfInterest(const reco::TrackRef &) const
define region of interest with tracker
Definition: DetId.h:17
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > theMuonRecHitBuilderToken
GlobalMuonTrackMatcher * theTrackMatcher
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
std::vector< std::unique_ptr< MuonCandidate > > CandidateContainer
Definition: MuonCandidate.h:18
GlobalVector const & direction() const
the direction around which region is constructed
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< Propagator > propagator(std::string propagatorName) const
get the propagator
MuonTrackingRegionBuilder * theRegionBuilder
const edm::EventSetup & eventSetup() const
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
std::vector< Trajectory > transform(const reco::Track &) const override
Convert a reco::Track into Trajectory.
static RecHitPointer build(const GeomDet *geom, const TrackingRecHit *rh)
FIXME virtual ConstMuonRecHitContainer specificTransientHits() const;.
float xx() const
Definition: LocalError.h:22
def move(src, dest)
Definition: eostools.py:511
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > theTrackerRecHitBuilderToken
Definition: event.py:1
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
#define LogDebug(id)
RefitDirection checkRecHitsOrdering(const ConstRecHitContainer &) const
This does nothing now.
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11