CMS 3D CMS Logo

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