CMS 3D CMS Logo

MuonTrackLoader.cc
Go to the documentation of this file.
1 
9 #include <memory>
10 
12 
16 
26 
28 
32 
37 
40 
43 
44 using namespace edm;
45 using namespace std;
46 using namespace reco;
47 
48 std::vector<const TrackingRecHit*> MuonTrackLoader::unpackHit(const TrackingRecHit& hit) {
49  // get rec hit det id and rec hit type
50  DetId id = hit.geographicalId();
51  uint16_t detid = id.det();
52 
53  std::vector<const TrackingRecHit*> hits;
54 
55  if (detid == DetId::Tracker) {
56  hits.push_back(&hit);
57  } else if (detid == DetId::Muon) {
58  uint16_t subdet = id.subdetId();
59  if (subdet == (uint16_t)MuonSubdetId::DT) {
60  if (hit.dimension() == 1) { // DT rechit (granularity 2)
61  hits.push_back(&hit);
62  } else if (hit.dimension() > 1) { // 4D segment (granularity 0).
63  // Both 2 and 4 dim cases. MB4s have 2D, but formatted in 4D segment
64  // 4D --> 2D
65  std::vector<const TrackingRecHit*> seg2D = hit.recHits();
66  // load 1D hits (2D --> 1D)
67  for (std::vector<const TrackingRecHit*>::const_iterator it = seg2D.begin(); it != seg2D.end(); ++it) {
68  std::vector<const TrackingRecHit*> hits1D = (*it)->recHits();
69  copy(hits1D.begin(), hits1D.end(), back_inserter(hits));
70  }
71  }
72  } else if (subdet == (uint16_t)MuonSubdetId::CSC) {
73  if (hit.dimension() == 2) { // CSC rechit (granularity 2)
74  hits.push_back(&hit);
75  } else if (hit.dimension() == 4) { // 4D segment (granularity 0)
76  // load 2D hits (4D --> 1D)
77  hits = hit.recHits();
78  }
79  } else if (subdet == (uint16_t)MuonSubdetId::RPC) {
80  hits.push_back(&hit);
81  } else if (subdet == (uint16_t)MuonSubdetId::GEM) {
82  if (hit.dimension() == 2) { // GEM rechit
83  hits.push_back(&hit);
84  } else if (hit.dimension() == 4) { // GEM segment
85  hits = hit.recHits();
86  }
87  } else if (subdet == (uint16_t)MuonSubdetId::ME0) { //segment
88  hits = hit.recHits();
89  }
90  }
91  return hits;
92 }
93 
94 // constructor (obsolete, should use eventSetUp not service..)
98  : theService(service) {
99  // option to do or not the smoothing step.
100  // the trajectories which are passed to the track loader are supposed to be non-smoothed
101  theSmoothingStep = parameterSet.getParameter<bool>("DoSmoothing");
102  if (theSmoothingStep) {
103  auto smootherName = parameterSet.getParameter<string>("Smoother");
104  theSmootherToken = iC.esConsumes(edm::ESInputTag("", smootherName));
105 
106  auto trackerRecHitBuilderName = parameterSet.getParameter<std::string>("TTRHBuilder");
107  theTrackerRecHitBuilderToken = iC.esConsumes(edm::ESInputTag("", trackerRecHitBuilderName));
108  }
109 
110  // update at vertex
111  theUpdatingAtVtx = parameterSet.getParameter<bool>("VertexConstraint");
112 
113  // beam spot input tag
116 
117  // Flag to put the trajectory into the event
118  theTrajectoryFlag = parameterSet.getUntrackedParameter<bool>("PutTrajectoryIntoEvent", true);
119 
120  theL2SeededTkLabel = parameterSet.getUntrackedParameter<string>("MuonSeededTracksInstance", string());
121 
122  ParameterSet updatorPar = parameterSet.getParameter<ParameterSet>("MuonUpdatorAtVertexParameters");
123  theUpdatorAtVtx = std::make_unique<MuonUpdatorAtVertex>(updatorPar, service);
124 
125  thePutTkTrackFlag = parameterSet.getUntrackedParameter<bool>("PutTkTrackIntoEvent", false);
126  theSmoothTkTrackFlag = parameterSet.getUntrackedParameter<bool>("SmoothTkTrack", false);
127  theAllowNoVtxFlag = parameterSet.getUntrackedParameter<bool>("AllowNoVertex", false);
128 }
129 
131 
133  Event& event,
134  const TrackerTopology& ttopo,
135  const string& instance,
136  bool reallyDoSmoothing) {
137  std::vector<bool> dummyVecBool;
138  return loadTracks(trajectories, event, dummyVecBool, ttopo, instance, reallyDoSmoothing);
139 }
140 
142  Event& event,
143  std::vector<bool>& tkBoolVec,
144  const TrackerTopology& ttopo,
145  const string& instance,
146  bool reallyDoSmoothing) {
147  const bool doSmoothing = theSmoothingStep && reallyDoSmoothing;
148 
149  const string metname = "Muon|RecoMuon|MuonTrackLoader";
150 
151  // the track collectios; they will be loaded in the event
152  auto trackCollection = std::make_unique<reco::TrackCollection>();
153  // ... and its reference into the event
154  reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
155 
156  // track collection for the tracks updated at vertex
157  auto updatedAtVtxTrackCollection = std::make_unique<reco::TrackCollection>();
158  // ... and its (eventually) reference into the event
159  reco::TrackRefProd trackUpdatedCollectionRefProd;
160  if (theUpdatingAtVtx)
161  trackUpdatedCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance + "UpdatedAtVtx");
162 
163  // Association map between updated and non updated at vtx tracks
164  auto trackToTrackmap = std::make_unique<reco::TrackToTrackMap>(trackCollectionRefProd, trackUpdatedCollectionRefProd);
165 
166  // the track extra collection, it will be loaded in the event
167  auto trackExtraCollection = std::make_unique<reco::TrackExtraCollection>();
168  // ... and its reference into the event
169  reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
170 
171  // the rechit collection, it will be loaded in the event
172  auto recHitCollection = std::make_unique<TrackingRecHitCollection>();
173  // ... and its reference into the event
174  TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
175 
176  // Collection of Trajectory
177  auto trajectoryCollection = std::make_unique<vector<Trajectory>>();
178 
179  // don't waste any time...
180  if (trajectories.empty()) {
181  event.put(std::move(recHitCollection), instance);
182  event.put(std::move(trackExtraCollection), instance);
183  if (theTrajectoryFlag) {
184  event.put(std::move(trajectoryCollection), instance);
185 
186  // Association map between track and trajectory
187  auto trajTrackMap = std::make_unique<TrajTrackAssociationCollection>();
188  event.put(std::move(trajTrackMap), instance);
189  }
190  if (theUpdatingAtVtx) {
191  event.put(std::move(trackToTrackmap));
192  event.put(std::move(updatedAtVtxTrackCollection), instance + "UpdatedAtVtx");
193  }
194  return event.put(std::move(trackCollection), instance);
195  }
196 
198  event.getByToken(theBeamSpotToken, beamSpot);
199 
200  LogTrace(metname) << "Create the collection of Tracks";
201 
202  reco::TrackRef::key_type trackIndex = 0;
203  reco::TrackRef::key_type trackUpdatedIndex = 0;
204 
205  reco::TrackExtraRef::key_type trackExtraIndex = 0;
206 
208  edm::Ref<std::vector<Trajectory>>::key_type iTjRef = 0;
209  std::map<unsigned int, unsigned int> tjTkMap;
210 
211  if (doSmoothing) {
212  TrajectorySmoother const& aSmoother = theService->eventSetup().getData(theSmootherToken);
213  theSmoother.reset(aSmoother.clone());
214  TransientTrackingRecHitBuilder const& theTrackerRecHitBuilder =
215  theService->eventSetup().getData(theTrackerRecHitBuilderToken);
216  hitCloner = static_cast<TkTransientTrackingRecHitBuilder const&>(theTrackerRecHitBuilder).cloner();
217  theSmoother->setHitCloner(&hitCloner);
218  }
219 
220  unsigned int tjCnt = 0;
221  for (TrajectoryContainer::iterator itRawTrajectory = trajectories.begin(); itRawTrajectory != trajectories.end();
222  ++itRawTrajectory, ++tjCnt) {
223  auto rawTrajectory = std::move(*itRawTrajectory);
224  Trajectory& trajectory = *rawTrajectory;
225 
226  if (doSmoothing) {
227  vector<Trajectory> trajectoriesSM = theSmoother->trajectories(*rawTrajectory);
228 
229  if (!trajectoriesSM.empty()) {
230  const edm::RefToBase<TrajectorySeed> tmpSeedRef = (*rawTrajectory).seedRef();
231  trajectory = trajectoriesSM.front();
232  trajectory.setSeedRef(tmpSeedRef);
233  LogDebug(metname) << "theSeedRef.isNonnull " << trajectory.seedRef().isNonnull();
234  } else
235  LogInfo(metname) << "The trajectory has not been smoothed!" << endl;
236  }
237 
238  if (theTrajectoryFlag) {
239  trajectoryCollection->push_back(trajectory);
240  iTjRef++;
241  }
242 
243  // build the "bare" track from the trajectory.
244  // This track has the parameters defined at PCA (no update)
245  pair<bool, reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
246 
247  // Check if the extrapolation went well
248  if (!resultOfTrackExtrapAtPCA.first) {
249  continue;
250  }
251 
252  // take the "bare" track at PCA
253  reco::Track& track = resultOfTrackExtrapAtPCA.second;
254 
255  // build the "bare" track extra from the trajectory
256  reco::TrackExtra trackExtra = buildTrackExtra(trajectory);
257 
258  // get the TrackExtraRef (persitent reference of the track extra)
259  reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++);
260 
261  // set the persistent track-extra reference to the Track
262  track.setExtra(trackExtraRef);
263 
264  // build the updated-at-vertex track, starting from the previous track
265  pair<bool, reco::Track> updateResult(false, reco::Track());
266 
267  if (theUpdatingAtVtx) {
268  // build the "bare" track UPDATED at vtx
269  updateResult = buildTrackUpdatedAtPCA(track, *beamSpot);
270 
271  if (!updateResult.first)
272  ++trackIndex;
273  else {
274  // set the persistent track-extra reference to the Track
275  updateResult.second.setExtra(trackExtraRef);
276 
277  // Fill the map
278  trackToTrackmap->insert(reco::TrackRef(trackCollectionRefProd, trackIndex++),
279  reco::TrackRef(trackUpdatedCollectionRefProd, trackUpdatedIndex++));
280  }
281  }
282 
283  // get the transient rechit and co from the trajectory
284  reco::TrackExtra::TrajParams trajParams;
286  Traj2TrackHits t2t;
287  auto ih = recHitCollection->size();
288  t2t(trajectory, *recHitCollection, trajParams, chi2s);
289  auto ie = recHitCollection->size();
290  // set the TrackingRecHitRef (persitent reference of the tracking rec hits)
291  trackExtra.setHits(recHitCollectionRefProd, ih, ie - ih);
292  trackExtra.setTrajParams(std::move(trajParams), std::move(chi2s));
293  assert(trackExtra.trajParams().size() == trackExtra.recHitsSize());
294 
295  // Fill the hit pattern
296  for (; ih < ie; ++ih) {
297  auto const& hit = (*recHitCollection)[ih];
299  for (auto hh : hits) {
300  if UNLIKELY (!track.appendHitPattern(*hh, ttopo))
301  break;
302  }
303 
304  if (theUpdatingAtVtx && updateResult.first) {
305  for (auto hh : hits) {
306  if UNLIKELY (!updateResult.second.appendHitPattern(*hh, ttopo))
307  break;
308  }
309  }
310  }
311 
312  // fill the TrackExtraCollection
313  trackExtraCollection->push_back(trackExtra);
314 
315  // fill the TrackCollection
316  trackCollection->push_back(track);
317  iTkRef++;
318  LogTrace(metname) << "Debug Track being loaded pt " << track.pt();
319  // fill the TrackCollection updated at vtx
320  if (theUpdatingAtVtx && updateResult.first)
321  updatedAtVtxTrackCollection->push_back(updateResult.second);
322 
323  if (tkBoolVec.size() > tjCnt)
324  tkBoolVec[tjCnt] = true;
325  if (theTrajectoryFlag)
326  tjTkMap[iTjRef - 1] = iTkRef - 1;
327  }
328 
329  // Put the Collections in the event
330  LogTrace(metname) << "put the Collections in the event";
331  event.put(std::move(recHitCollection), instance);
332  event.put(std::move(trackExtraCollection), instance);
333 
334  OrphanHandle<reco::TrackCollection> returnTrackHandle;
335  OrphanHandle<reco::TrackCollection> nonUpdatedHandle;
336  if (theUpdatingAtVtx) {
337  nonUpdatedHandle = event.put(std::move(trackCollection), instance);
338  event.put(std::move(trackToTrackmap));
339  returnTrackHandle = event.put(std::move(updatedAtVtxTrackCollection), instance + "UpdatedAtVtx");
340  } else {
341  returnTrackHandle = event.put(std::move(trackCollection), instance);
342  nonUpdatedHandle = returnTrackHandle;
343  }
344 
345  if (theTrajectoryFlag) {
346  OrphanHandle<std::vector<Trajectory>> rTrajs = event.put(std::move(trajectoryCollection), instance);
347 
348  // Association map between track and trajectory
349  auto trajTrackMap = std::make_unique<TrajTrackAssociationCollection>(rTrajs, nonUpdatedHandle);
350 
351  // Now Create traj<->tracks association map
352  for (std::map<unsigned int, unsigned int>::iterator i = tjTkMap.begin(); i != tjTkMap.end(); i++) {
353  trajTrackMap->insert(edm::Ref<std::vector<Trajectory>>(rTrajs, (*i).first),
354  edm::Ref<reco::TrackCollection>(nonUpdatedHandle, (*i).second));
355  }
356  event.put(std::move(trajTrackMap), instance);
357  }
358 
359  return returnTrackHandle;
360 }
361 
363  Event& event,
364  const TrackerTopology& ttopo) {
365  const string metname = "Muon|RecoMuon|MuonTrackLoader";
366 
367  // the muon collection, it will be loaded in the event
368  auto trackLinksCollection = std::make_unique<reco::MuonTrackLinksCollection>();
369 
370  // don't waste any time...
371  if (muonCands.empty()) {
372  auto trackExtraCollection = std::make_unique<reco::TrackExtraCollection>();
373  auto recHitCollection = std::make_unique<TrackingRecHitCollection>();
374  auto trackCollection = std::make_unique<reco::TrackCollection>();
375 
376  event.put(std::move(recHitCollection));
377  event.put(std::move(trackExtraCollection));
378  event.put(std::move(trackCollection));
379 
380  //need to also put the tracker tracks collection if requested
381  if (thePutTkTrackFlag) {
382  //will take care of putting nothing in the event but the empty collection
383  TrajectoryContainer trackerTrajs;
385  }
386 
387  return event.put(std::move(trackLinksCollection));
388  }
389 
390  // get combined Trajectories
391  TrajectoryContainer combinedTrajs;
392  TrajectoryContainer trackerTrajs;
393  for (CandidateContainer::iterator it = muonCands.begin(); it != muonCands.end(); ++it) {
394  LogDebug(metname) << "Loader glbSeedRef " << (*it)->trajectory()->seedRef().isNonnull();
395  if ((*it)->trackerTrajectory())
396  LogDebug(metname) << " "
397  << "tkSeedRef " << (*it)->trackerTrajectory()->seedRef().isNonnull();
398 
399  combinedTrajs.push_back((*it)->releaseTrajectory());
400  {
401  auto tt = (*it)->releaseTrackerTrajectory();
402  if (thePutTkTrackFlag)
403  trackerTrajs.push_back(std::move(tt));
404  }
405 
406  // // Create the links between sta and tracker tracks
407  // reco::MuonTrackLinks links;
408  // links.setStandAloneTrack((*it)->muonTrack());
409  // links.setTrackerTrack((*it)->trackerTrack());
410  // trackLinksCollection->push_back(links);
411  // delete *it;
412  }
413 
414  // create the TrackCollection of combined Trajectories
415  // FIXME: could this be done one track at a time in the previous loop?
416  LogTrace(metname) << "Build combinedTracks";
417  std::vector<bool> combTksVec(combinedTrajs.size(), false);
418  OrphanHandle<reco::TrackCollection> combinedTracks = loadTracks(combinedTrajs, event, combTksVec, ttopo);
419 
421  std::vector<bool> trackerTksVec(trackerTrajs.size(), false);
422  if (thePutTkTrackFlag) {
423  LogTrace(metname) << "Build trackerTracks: " << trackerTrajs.size();
424  trackerTracks = loadTracks(trackerTrajs, event, trackerTksVec, ttopo, theL2SeededTkLabel, theSmoothTkTrackFlag);
425  }
426 
427  trackerTrajs.clear();
428 
429  LogTrace(metname) << "Set the final links in the MuonTrackLinks collection";
430 
431  unsigned int candposition(0), position(0), tkposition(0);
432  //reco::TrackCollection::const_iterator glIt = combinedTracks->begin(),
433  // glEnd = combinedTracks->end();
434 
435  for (CandidateContainer::const_iterator it = muonCands.begin(); it != muonCands.end(); ++it, ++candposition) {
436  // The presence of the global track determines whether to fill the MuonTrackLinks or not
437  // N.B. We are assuming here that the global tracks in "combinedTracks"
438  // have the same order as the muon candidates in "muonCands"
439  // (except for possible missing tracks), which should always be the case...
440  //if( glIt == glEnd ) break;
441  if (combTksVec[candposition]) {
442  reco::TrackRef combinedTR(combinedTracks, position++);
443  //++glIt;
444 
445  // Create the links between sta and tracker tracks
447  links.setStandAloneTrack((*it)->muonTrack());
448  links.setTrackerTrack((*it)->trackerTrack());
449  links.setGlobalTrack(combinedTR);
450 
451  if (thePutTkTrackFlag && trackerTksVec[candposition]) {
452  reco::TrackRef trackerTR(trackerTracks, tkposition++);
453  links.setTrackerTrack(trackerTR);
454  }
455 
456  trackLinksCollection->push_back(links);
457  }
458 
459  else { // if no global track, still increment the tracker-track counter when appropriate
460  if (thePutTkTrackFlag && trackerTksVec[candposition])
461  tkposition++;
462  }
463  }
464 
465  if (thePutTkTrackFlag && trackerTracks.isValid() && !(!combinedTracks->empty() && !trackerTracks->empty()))
466  LogWarning(metname) << "The MuonTrackLinkCollection is incomplete";
467 
468  // put the MuonCollection in the event
469  LogTrace(metname) << "put the MuonCollection in the event"
470  << "\n";
471 
472  return event.put(std::move(trackLinksCollection));
473 }
474 
476  TrajectoryContainer& trajectories,
477  Event& event,
478  const std::vector<std::pair<Trajectory*, reco::TrackRef>>& miniMap,
479  Handle<reco::TrackCollection> const& trackHandle,
480  const TrackerTopology& ttopo,
481  const string& instance,
482  bool reallyDoSmoothing) {
483  const bool doSmoothing = theSmoothingStep && reallyDoSmoothing;
484 
485  const string metname = "Muon|RecoMuon|MuonTrackLoader|TevMuonTrackLoader";
486 
487  LogDebug(metname) << "TeV LoadTracks instance: " << instance;
488 
489  // the track collectios; they will be loaded in the event
490  auto trackCollection = std::make_unique<reco::TrackCollection>();
491  // ... and its reference into the event
492  reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
493 
494  // Association map between GlobalMuons and TeVMuons
495  auto trackToTrackmap = std::make_unique<reco::TrackToTrackMap>(trackHandle, trackCollectionRefProd);
496 
497  // the track extra collection, it will be loaded in the event
498  auto trackExtraCollection = std::make_unique<reco::TrackExtraCollection>();
499  // ... and its reference into the event
500  reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
501 
502  // the rechit collection, it will be loaded in the event
503  auto recHitCollection = std::make_unique<TrackingRecHitCollection>();
504  // ... and its reference into the event
505  TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
506 
507  // Collection of Trajectory
508  auto trajectoryCollection = std::make_unique<std::vector<Trajectory>>();
509 
510  // don't waste any time...
511  if (trajectories.empty()) {
512  event.put(std::move(recHitCollection), instance);
513  event.put(std::move(trackExtraCollection), instance);
514  if (theTrajectoryFlag) {
515  event.put(std::move(trajectoryCollection), instance);
516 
517  // Association map between track and trajectory
518  auto trajTrackMap = std::make_unique<TrajTrackAssociationCollection>();
519  event.put(std::move(trajTrackMap), instance);
520  }
521  event.put(std::move(trackToTrackmap), instance);
522  return event.put(std::move(trackCollection), instance);
523  }
524 
525  LogTrace(metname) << "Create the collection of Tracks";
526 
528  event.getByToken(theBeamSpotToken, beamSpot);
529 
530  reco::TrackRef::key_type trackIndex = 0;
531 
532  reco::TrackExtraRef::key_type trackExtraIndex = 0;
533 
535  edm::Ref<std::vector<Trajectory>>::key_type iTjRef = 0;
536  std::map<unsigned int, unsigned int> tjTkMap;
537 
538  if (doSmoothing) {
539  TrajectorySmoother const& aSmoother = theService->eventSetup().getData(theSmootherToken);
540  theSmoother.reset(aSmoother.clone());
541  TransientTrackingRecHitBuilder const& theTrackerRecHitBuilder =
542  theService->eventSetup().getData(theTrackerRecHitBuilderToken);
543  hitCloner = static_cast<TkTransientTrackingRecHitBuilder const&>(theTrackerRecHitBuilder).cloner();
544  theSmoother->setHitCloner(&hitCloner);
545  }
546 
547  for (TrajectoryContainer::iterator itRawTrajectory = trajectories.begin(); itRawTrajectory != trajectories.end();
548  ++itRawTrajectory) {
549  auto rawTrajectory = std::move(*itRawTrajectory);
550  reco::TrackRef glbRef;
551  std::vector<std::pair<Trajectory*, reco::TrackRef>>::const_iterator mmit;
552  for (mmit = miniMap.begin(); mmit != miniMap.end(); ++mmit) {
553  if (mmit->first == rawTrajectory.get())
554  glbRef = mmit->second;
555  }
556 
557  Trajectory& trajectory = *rawTrajectory;
558 
559  if (doSmoothing) {
560  vector<Trajectory> trajectoriesSM = theSmoother->trajectories(*rawTrajectory);
561 
562  if (!trajectoriesSM.empty()) {
563  const edm::RefToBase<TrajectorySeed> tmpSeedRef = (*rawTrajectory).seedRef();
564  trajectory = trajectoriesSM.front();
565  trajectory.setSeedRef(tmpSeedRef);
566  } else
567  LogInfo(metname) << "The trajectory has not been smoothed!" << endl;
568  }
569 
570  if (theTrajectoryFlag) {
571  trajectoryCollection->push_back(trajectory);
572  iTjRef++;
573  }
574 
575  // build the "bare" track from the trajectory.
576  // This track has the parameters defined at PCA (no update)
577  pair<bool, reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
578 
579  // Check if the extrapolation went well
580  if (!resultOfTrackExtrapAtPCA.first) {
581  continue;
582  }
583 
584  // take the "bare" track at PCA
585  reco::Track& track = resultOfTrackExtrapAtPCA.second;
586 
587  // build the "bare" track extra from the trajectory
588  reco::TrackExtra trackExtra = buildTrackExtra(trajectory);
589 
590  // get the TrackExtraRef (persitent reference of the track extra)
591  reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++);
592 
593  // set the persistent track-extra reference to the Track
594  track.setExtra(trackExtraRef);
595 
596  // Fill the map
597  trackToTrackmap->insert(glbRef, reco::TrackRef(trackCollectionRefProd, trackIndex++));
598 
599  // build the updated-at-vertex track, starting from the previous track
600  pair<bool, reco::Track> updateResult(false, reco::Track());
601 
602  // get the transient rechit and co from the trajectory
603  reco::TrackExtra::TrajParams trajParams;
605  Traj2TrackHits t2t;
606  auto ih = recHitCollection->size();
607  t2t(trajectory, *recHitCollection, trajParams, chi2s);
608  auto ie = recHitCollection->size();
609  // set the TrackingRecHitRef (persitent reference of the tracking rec hits)
610  trackExtra.setHits(recHitCollectionRefProd, ih, ie - ih);
611  trackExtra.setTrajParams(std::move(trajParams), std::move(chi2s));
612  assert(trackExtra.trajParams().size() == trackExtra.recHitsSize());
613 
614  // Fill the hit pattern
615  for (; ih < ie; ++ih) {
616  auto const& hit = (*recHitCollection)[ih];
618  for (auto hh : hits) {
619  if UNLIKELY (!track.appendHitPattern(*hh, ttopo))
620  break;
621  }
622 
623  if (theUpdatingAtVtx && updateResult.first) {
624  for (auto hh : hits) {
625  if UNLIKELY (!updateResult.second.appendHitPattern(*hh, ttopo))
626  break;
627  }
628  }
629  }
630 
631  // fill the TrackExtraCollection
632  trackExtraCollection->push_back(trackExtra);
633 
634  // fill the TrackCollection
635  trackCollection->push_back(track);
636  iTkRef++;
637  LogTrace(metname) << "Debug Track being loaded pt " << track.pt();
638 
639  if (theTrajectoryFlag)
640  tjTkMap[iTjRef - 1] = iTkRef - 1;
641  }
642 
643  // Put the Collections in the event
644  LogTrace(metname) << "put the Collections in the event";
645  event.put(std::move(recHitCollection), instance);
646  event.put(std::move(trackExtraCollection), instance);
647 
648  OrphanHandle<reco::TrackCollection> returnTrackHandle;
649  OrphanHandle<reco::TrackCollection> nonUpdatedHandle;
650  if (theUpdatingAtVtx) {
651  } else {
652  event.put(std::move(trackToTrackmap), instance);
653  returnTrackHandle = event.put(std::move(trackCollection), instance);
654  nonUpdatedHandle = returnTrackHandle;
655  }
656 
657  if (theTrajectoryFlag) {
658  OrphanHandle<std::vector<Trajectory>> rTrajs = event.put(std::move(trajectoryCollection), instance);
659 
660  // Association map between track and trajectory
661  auto trajTrackMap = std::make_unique<TrajTrackAssociationCollection>(rTrajs, nonUpdatedHandle);
662 
663  // Now Create traj<->tracks association map
664  for (std::map<unsigned int, unsigned int>::iterator i = tjTkMap.begin(); i != tjTkMap.end(); i++) {
665  trajTrackMap->insert(edm::Ref<std::vector<Trajectory>>(rTrajs, (*i).first),
666  edm::Ref<reco::TrackCollection>(nonUpdatedHandle, (*i).second));
667  }
668  event.put(std::move(trajTrackMap), instance);
669  }
670 
671  return returnTrackHandle;
672 }
673 
674 pair<bool, reco::Track> MuonTrackLoader::buildTrackAtPCA(const Trajectory& trajectory,
675  const reco::BeamSpot& beamSpot) const {
676  const string metname = "Muon|RecoMuon|MuonTrackLoader";
677 
679 
680  // FIXME: check the prop direction
681  TrajectoryStateOnSurface innerTSOS = trajectory.geometricalInnermostState();
682 
683  // This is needed to extrapolate the tsos at vertex
684  LogTrace(metname) << "Propagate to PCA...";
685  pair<bool, FreeTrajectoryState> extrapolationResult = theUpdatorAtVtx->propagate(innerTSOS, beamSpot);
686  FreeTrajectoryState ftsAtVtx;
687 
688  if (extrapolationResult.first)
689  ftsAtVtx = extrapolationResult.second;
690  else {
691  if (TrackerBounds::isInside(innerTSOS.globalPosition())) {
692  LogInfo(metname) << "Track in the Tracker: taking the innermost state instead of the state at PCA";
693  ftsAtVtx = *innerTSOS.freeState();
694  } else {
695  if (theAllowNoVtxFlag) {
696  LogInfo(metname) << "Propagation to PCA failed, taking the innermost state instead of the state at PCA";
697  ftsAtVtx = *innerTSOS.freeState();
698  } else {
699  LogInfo(metname) << "Stand Alone track: this track will be rejected";
700  return pair<bool, reco::Track>(false, reco::Track());
701  }
702  }
703  }
704 
705  LogTrace(metname) << "TSOS after the extrapolation at vtx";
706  LogTrace(metname) << debug.dumpFTS(ftsAtVtx);
707 
708  GlobalPoint pca = ftsAtVtx.position();
709  math::XYZPoint persistentPCA(pca.x(), pca.y(), pca.z());
710  GlobalVector p = ftsAtVtx.momentum();
711  math::XYZVector persistentMomentum(p.x(), p.y(), p.z());
712 
713  bool bon = true;
714  if (fabs(theService->magneticField()->inTesla(GlobalPoint(0, 0, 0)).z()) < 0.01)
715  bon = false;
716  double ndof = trajectory.ndof(bon);
717 
719  trajectory.chiSquared(), ndof, persistentPCA, persistentMomentum, ftsAtVtx.charge(), ftsAtVtx.curvilinearError());
720 
721  return pair<bool, reco::Track>(true, track);
722 }
723 
725  const reco::BeamSpot& beamSpot) const {
726  const string metname = "Muon|RecoMuon|MuonTrackLoader";
728 
729  // build the transient track
730  reco::TransientTrack transientTrack(track, &*theService->magneticField(), theService->trackingGeometry());
731 
732  LogTrace(metname) << "Apply the vertex constraint";
733  pair<bool, FreeTrajectoryState> updateResult = theUpdatorAtVtx->update(transientTrack, beamSpot);
734 
735  if (!updateResult.first) {
736  return pair<bool, reco::Track>(false, reco::Track());
737  }
738 
739  LogTrace(metname) << "FTS after the vertex constraint";
740  FreeTrajectoryState& ftsAtVtx = updateResult.second;
741 
742  LogTrace(metname) << debug.dumpFTS(ftsAtVtx);
743 
744  GlobalPoint pca = ftsAtVtx.position();
745  math::XYZPoint persistentPCA(pca.x(), pca.y(), pca.z());
746  GlobalVector p = ftsAtVtx.momentum();
747  math::XYZVector persistentMomentum(p.x(), p.y(), p.z());
748 
749  reco::Track updatedTrack(
750  track.chi2(), track.ndof(), persistentPCA, persistentMomentum, ftsAtVtx.charge(), ftsAtVtx.curvilinearError());
751 
752  return pair<bool, reco::Track>(true, updatedTrack);
753 }
754 
756  const string metname = "Muon|RecoMuon|MuonTrackLoader";
757 
758  const Trajectory::RecHitContainer transRecHits = trajectory.recHits();
759 
760  // put the collection of TrackingRecHit in the event
761 
762  // sets the outermost and innermost TSOSs
763  // FIXME: check it!
764  TrajectoryStateOnSurface outerTSOS;
765  TrajectoryStateOnSurface innerTSOS;
766  unsigned int innerId = 0, outerId = 0;
768  DetId outerDetId;
769 
770  if (trajectory.direction() == alongMomentum) {
771  LogTrace(metname) << "alongMomentum";
772  outerTSOS = trajectory.lastMeasurement().updatedState();
773  innerTSOS = trajectory.firstMeasurement().updatedState();
774  outerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId();
775  innerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId();
776  outerRecHit = trajectory.lastMeasurement().recHit();
777  outerDetId = trajectory.lastMeasurement().recHit()->geographicalId();
778  } else if (trajectory.direction() == oppositeToMomentum) {
779  LogTrace(metname) << "oppositeToMomentum";
780  outerTSOS = trajectory.firstMeasurement().updatedState();
781  innerTSOS = trajectory.lastMeasurement().updatedState();
782  outerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId();
783  innerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId();
784  outerRecHit = trajectory.firstMeasurement().recHit();
785  outerDetId = trajectory.firstMeasurement().recHit()->geographicalId();
786  } else
787  LogError(metname) << "Wrong propagation direction!";
788 
789  const GeomDet* outerDet = theService->trackingGeometry()->idToDet(outerDetId);
790  GlobalPoint outerTSOSPos = outerTSOS.globalParameters().position();
791  bool inside = outerDet->surface().bounds().inside(outerDet->toLocal(outerTSOSPos));
792 
793  GlobalPoint hitPos =
794  (outerRecHit->isValid()) ? outerRecHit->globalPosition() : outerTSOS.globalParameters().position();
795 
796  if (!inside) {
797  LogTrace(metname) << "The Global Muon outerMostMeasurementState is not compatible with the recHit detector! "
798  "Setting outerMost postition to recHit position if recHit isValid: "
799  << outerRecHit->isValid();
800  LogTrace(metname) << "From " << outerTSOSPos << " to " << hitPos;
801  }
802 
803  //build the TrackExtra
804  GlobalPoint v = (inside) ? outerTSOSPos : hitPos;
805  GlobalVector p = outerTSOS.globalParameters().momentum();
806  math::XYZPoint outpos(v.x(), v.y(), v.z());
807  math::XYZVector outmom(p.x(), p.y(), p.z());
808 
809  v = innerTSOS.globalParameters().position();
810  p = innerTSOS.globalParameters().momentum();
811  math::XYZPoint inpos(v.x(), v.y(), v.z());
812  math::XYZVector inmom(p.x(), p.y(), p.z());
813 
814  reco::TrackExtra trackExtra(outpos,
815  outmom,
816  true,
817  inpos,
818  inmom,
819  true,
820  outerTSOS.curvilinearError(),
821  outerId,
822  innerTSOS.curvilinearError(),
823  innerId,
824  trajectory.direction(),
825  trajectory.seedRef());
826 
827  return trackExtra;
828 }
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
edm::EDGetTokenT< reco::BeamSpot > theBeamSpotToken
std::unique_ptr< TrajectorySmoother > theSmoother
MuonTrackLoader(edm::ParameterSet &parameterSet, edm::ConsumesCollector &iC, const MuonServiceProxy *service=nullptr)
Constructor for the STA reco the args must be specify!
std::unique_ptr< MuonUpdatorAtVertex > theUpdatorAtVtx
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::remove_cv< typename std::remove_reference< argument_type >::type >::type key_type
Definition: Ref.h:164
std::pair< bool, reco::Track > buildTrackAtPCA(const Trajectory &trajectory, const reco::BeamSpot &) const
Build a track at the PCA WITHOUT any vertex constriant.
TrajParams const & trajParams() const
static bool isInside(const GlobalPoint &)
static constexpr int GEM
Definition: MuonSubdetId.h:14
const CurvilinearTrajectoryError & curvilinearError() const
std::vector< unsigned char > Chi2sFive
virtual bool inside(const Local3DPoint &) const =0
Determine if the point is inside the bounds.
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:58
static PFTauRenderPlugin instance
T z() const
Definition: PV3DBase.h:61
const std::string metname
reco::TrackExtra buildTrackExtra(const Trajectory &) const
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:303
void setHits(TrackingRecHitRefProd const &prod, unsigned firstH, unsigned int nH)
TrajectoryStateOnSurface geometricalInnermostState() const
Definition: Trajectory.cc:217
unsigned int recHitsSize() const
number of RecHits
TkClonerImpl hitCloner
const GlobalTrajectoryParameters & globalParameters() const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
static std::vector< const TrackingRecHit * > unpackHit(const TrackingRecHit &hit)
float chiSquared() const
Definition: Trajectory.h:241
edm::RefToBase< TrajectorySeed > seedRef(void) const
Definition: Trajectory.h:303
Log< level::Error, false > LogError
assert(be >=bs)
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
TrajectoryMeasurement const & lastMeasurement() const
Definition: Trajectory.h:150
#define LogTrace(id)
MuonCandidate::CandidateContainer CandidateContainer
const MuonServiceProxy * theService
T getUntrackedParameter(std::string const &, T const &) const
GlobalPoint position() const
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
std::vector< LocalTrajectoryParameters > TrajParams
void push_back(D *&d)
Definition: OwnVector.h:326
Definition: TTTypes.h:54
int ndof(bool bon=true) const
Definition: Trajectory.cc:97
GlobalPoint globalPosition() const
edm::InputTag theBeamSpotInputTag
edm::OrphanHandle< reco::TrackCollection > loadTracks(TrajectoryContainer &, edm::Event &, const TrackerTopology &ttopo, const std::string &="", bool=true)
Convert the trajectories into tracks and load the tracks in the event.
PropagationDirection const & direction() const
Definition: Trajectory.cc:133
virtual ~MuonTrackLoader()
Destructor.
TrackCharge charge() const
ConstRecHitContainer recHits() const
Definition: Trajectory.h:186
GlobalVector momentum() const
virtual TrajectorySmoother * clone() const =0
static constexpr int ME0
Definition: MuonSubdetId.h:15
trackCollection
Definition: JetHT_cfg.py:51
MuonCandidate::TrajectoryContainer TrajectoryContainer
Log< level::Info, false > LogInfo
Definition: DetId.h:17
std::vector< TrackExtra > TrackExtraCollection
collection of TrackExtra objects
Definition: TrackExtraFwd.h:10
ConstRecHitContainer RecHitContainer
Definition: Trajectory.h:42
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
#define debug
Definition: HDRShower.cc:19
const CurvilinearTrajectoryError & curvilinearError() const
std::string theL2SeededTkLabel
Label for L2SeededTracks.
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
static constexpr int RPC
Definition: MuonSubdetId.h:13
TrackingRecHit::ConstRecHitPointer ConstRecHitPointer
void setSeedRef(const edm::RefToBase< TrajectorySeed > &seedRef)
Definition: Trajectory.h:305
TrajectoryStateOnSurface const & updatedState() const
fixed size matrix
HLT enums.
TrajectoryMeasurement const & firstMeasurement() const
Definition: Trajectory.h:166
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > theTrackerRecHitBuilderToken
static int position[264][3]
Definition: ReadPGInfo.cc:289
FreeTrajectoryState const * freeState(bool withErrors=true) const
const MuonServiceProxy * theService
edm::ESGetToken< TrajectorySmoother, TrajectoryFitter::Record > theSmootherToken
std::pair< bool, reco::Track > buildTrackUpdatedAtPCA(const reco::Track &trackAtPCA, const reco::BeamSpot &) const
Takes a track at the PCA and applies the vertex constriant.
TupleMultiplicity< TrackerTraits > const *__restrict__ TrackingRecHitSoAConstView< TrackerTraits > hh
#define UNLIKELY(x)
Definition: Likely.h:21
static constexpr int DT
Definition: MuonSubdetId.h:11
Log< level::Warning, false > LogWarning
static constexpr int CSC
Definition: MuonSubdetId.h:12
def move(src, dest)
Definition: eostools.py:511
void setTrajParams(TrajParams tmps, Chi2sFive chi2s)
Definition: event.py:1
ConstRecHitPointer const & recHit() const
#define LogDebug(id)
const Bounds & bounds() const
Definition: Surface.h:87