CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GlobalMuonRefitter.cc
Go to the documentation of this file.
1 
16 
17 //---------------
18 // C++ Headers --
19 //---------------
20 
21 #include <iostream>
22 #include <iomanip>
23 #include <algorithm>
24 
25 //-------------------------------
26 // Collaborating Class Headers --
27 //-------------------------------
28 
30 
40 
41 
54 
64 
65 using namespace std;
66 using namespace edm;
67 
68 //----------------
69 // Constructors --
70 //----------------
71 
73  const MuonServiceProxy* service,
75  theCosmicFlag(par.getParameter<bool>("PropDirForCosmics")),
76  theDTRecHitLabel(par.getParameter<InputTag>("DTRecSegmentLabel")),
77  theCSCRecHitLabel(par.getParameter<InputTag>("CSCRecSegmentLabel")),
78  theGEMRecHitLabel(par.getParameter<InputTag>("GEMRecHitLabel")),
79  theService(service) {
80 
81  theCategory = par.getUntrackedParameter<string>("Category", "Muon|RecoMuon|GlobalMuon|GlobalMuonRefitter");
82 
83  theHitThreshold = par.getParameter<int>("HitThreshold");
84  theDTChi2Cut = par.getParameter<double>("Chi2CutDT");
85  theCSCChi2Cut = par.getParameter<double>("Chi2CutCSC");
86  theRPCChi2Cut = par.getParameter<double>("Chi2CutRPC");
87  theGEMChi2Cut = par.getParameter<double>("Chi2CutGEM");
88 
89  // Refit direction
90  string refitDirectionName = par.getParameter<string>("RefitDirection");
91 
92  if (refitDirectionName == "insideOut" ) theRefitDirection = insideOut;
93  else if (refitDirectionName == "outsideIn" ) theRefitDirection = outsideIn;
94  else
95  throw cms::Exception("TrackTransformer constructor")
96  <<"Wrong refit direction chosen in TrackTransformer ParameterSet"
97  << "\n"
98  << "Possible choices are:"
99  << "\n"
100  << "RefitDirection = insideOut or RefitDirection = outsideIn";
101 
102  theFitterName = par.getParameter<string>("Fitter");
103  thePropagatorName = par.getParameter<string>("Propagator");
104 
105  theSkipStation = par.getParameter<int>("SkipStation");
106  theTrackerSkipSystem = par.getParameter<int>("TrackerSkipSystem");
107  theTrackerSkipSection = par.getParameter<int>("TrackerSkipSection");//layer, wheel, or disk depending on the system
108 
109  theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
110  theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
111 
112  theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
113 
114  theDYTthrs = par.getParameter< std::vector<int> >("DYTthrs");
115  theDYTselector = par.existsAs<int>("DYTselector")?par.getParameter<int>("DYTselector"):1;
116  theDYTupdator = par.existsAs<bool>("DYTupdator")?par.getParameter<bool>("DYTupdator"):false;
117  theDYTuseAPE = par.existsAs<bool>("DYTuseAPE")?par.getParameter<bool>("DYTuseAPE"):false;
118  dytInfo = new reco::DYTInfo();
119 
120  if (par.existsAs<double>("RescaleErrorFactor")) {
121  theRescaleErrorFactor = par.getParameter<double>("RescaleErrorFactor");
122  edm::LogWarning("GlobalMuonRefitter") << "using error rescale factor " << theRescaleErrorFactor;
123  }
124  else
125  theRescaleErrorFactor = 1000.;
126 
127  theCacheId_TRH = 0;
133 }
134 
135 //--------------
136 // Destructor --
137 //--------------
138 
140  delete dytInfo;
141 }
142 
143 
144 //
145 // set Event
146 //
148 
149  theEvent = &event;
150  event.getByToken(theDTRecHitToken, theDTRecHits);
151  event.getByToken(theCSCRecHitToken, theCSCRecHits);
152  event.getByToken(theGEMRecHitToken, theGEMRecHits);
153  event.getByToken(CSCSegmentsToken, CSCSegments);
154  event.getByToken(all4DSegmentsToken, all4DSegments);
155 }
156 
157 
159 
161  theService->eventSetup().get<TrajectoryFitter::Record>().get(theFitterName,aFitter);
162  theFitter = aFitter->clone();
163 
164 
165  // Transient Rechit Builders
166  unsigned long long newCacheId_TRH = setup.get<TransientRecHitRecord>().cacheIdentifier();
167  if ( newCacheId_TRH != theCacheId_TRH ) {
168  LogDebug(theCategory) << "TransientRecHitRecord changed!";
172  }
173  theFitter->setHitCloner(&hitCloner);
174 
175 }
176 
177 
178 //
179 // build a combined tracker-muon trajectory
180 //
181 vector<Trajectory> GlobalMuonRefitter::refit(const reco::Track& globalTrack,
182  const int theMuonHitsOption,
183  const TrackerTopology *tTopo) const {
184  LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
185 
186  ConstRecHitContainer allRecHitsTemp; // all muon rechits temp
187 
188  reco::TransientTrack track(globalTrack,&*(theService->magneticField()),theService->trackingGeometry());
189 
190  auto tkbuilder = static_cast<TkTransientTrackingRecHitBuilder const *>(theTrackerRecHitBuilder.product());
191 
192  for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit)
193  if ((*hit)->isValid()) {
194  if ((*hit)->geographicalId().det() == DetId::Tracker)
195  allRecHitsTemp.push_back((**hit).cloneForFit(*tkbuilder->geometry()->idToDet( (**hit).geographicalId() ) ) );
196  else if ((*hit)->geographicalId().det() == DetId::Muon) {
197  if ((*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit) {
198  LogTrace(theCategory) << "RPC Rec Hit discarged";
199  continue;
200  }
201  allRecHitsTemp.push_back(theMuonRecHitBuilder->build(&**hit));
202  }
203  }
204  vector<Trajectory> refitted = refit(globalTrack,track,allRecHitsTemp,theMuonHitsOption, tTopo);
205  return refitted;
206 }
207 
208 //
209 // build a combined tracker-muon trajectory
210 //
211 vector<Trajectory> GlobalMuonRefitter::refit(const reco::Track& globalTrack,
212  const reco::TransientTrack track,
213  const TransientTrackingRecHit::ConstRecHitContainer& allRecHitsTemp,
214  const int theMuonHitsOption,
215  const TrackerTopology *tTopo) const {
216 
217  // MuonHitsOption: 0 - tracker only
218  // 1 - include all muon hits
219  // 2 - include only first muon hit(s)
220  // 3 - include only selected muon hits
221  // 4 - redo pattern recognition with dynamic truncation
222 
223  vector<int> stationHits(4,0);
224  map<DetId, int> hitMap;
225 
226  ConstRecHitContainer allRecHits; // all muon rechits
227  ConstRecHitContainer fmsRecHits; // only first muon rechits
228  ConstRecHitContainer selectedRecHits; // selected muon rechits
229  ConstRecHitContainer DYTRecHits; // rec hits from dynamic truncation algorithm
230 
231  LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
232  LogTrace(theCategory) << " Track momentum before refit: " << globalTrack.pt() << endl;
233  LogTrace(theCategory) << " Hits size before : " << allRecHitsTemp.size() << endl;
234 
235  allRecHits = getRidOfSelectStationHits(allRecHitsTemp, tTopo);
236  // printHits(allRecHits);
237  LogTrace(theCategory) << " Hits size: " << allRecHits.size() << endl;
238 
239  vector <Trajectory> outputTraj;
240 
241  if ((theMuonHitsOption == 1) || (theMuonHitsOption == 3) || (theMuonHitsOption == 4) ) {
242  // refit the full track with all muon hits
243  vector <Trajectory> globalTraj = transform(globalTrack, track, allRecHits);
244 
245  if (!globalTraj.size()) {
246  LogTrace(theCategory) << "No trajectory from the TrackTransformer!" << endl;
247  return vector<Trajectory>();
248  }
249 
250  LogTrace(theCategory) << " Initial trajectory state: "
251  << globalTraj.front().lastMeasurement().updatedState().freeState()->parameters() << endl;
252 
253  if (theMuonHitsOption == 1 )
254  outputTraj.push_back(globalTraj.front());
255 
256  if (theMuonHitsOption == 3 ) {
257  checkMuonHits(globalTrack, allRecHits, hitMap);
258  selectedRecHits = selectMuonHits(globalTraj.front(),hitMap);
259  LogTrace(theCategory) << " Selected hits size: " << selectedRecHits.size() << endl;
260  outputTraj = transform(globalTrack, track, selectedRecHits);
261  }
262 
263  if (theMuonHitsOption == 4 ) {
264  //
265  // DYT 2.0
266  //
268  dytRefit.setProd(all4DSegments, CSCSegments);
269  dytRefit.setSelector(theDYTselector);
270  dytRefit.setThr(theDYTthrs);
271  dytRefit.setUpdateState(theDYTupdator);
272  dytRefit.setUseAPE(theDYTuseAPE);
273  DYTRecHits = dytRefit.filter(globalTraj.front());
274  dytInfo->CopyFrom(dytRefit.getDYTInfo());
275  if ((DYTRecHits.size() > 1) && (DYTRecHits.front()->globalPosition().mag() > DYTRecHits.back()->globalPosition().mag()))
276  stable_sort(DYTRecHits.begin(),DYTRecHits.end(),RecHitLessByDet(alongMomentum));
277  outputTraj = transform(globalTrack, track, DYTRecHits);
278  }
279 
280  } else if (theMuonHitsOption == 2 ) {
281  getFirstHits(globalTrack, allRecHits, fmsRecHits);
282  outputTraj = transform(globalTrack, track, fmsRecHits);
283  }
284 
285 
286  if (outputTraj.size()) {
287  LogTrace(theCategory) << "Refitted pt: " << outputTraj.front().firstMeasurement().updatedState().globalParameters().momentum().perp() << endl;
288  return outputTraj;
289  } else {
290  LogTrace(theCategory) << "No refitted Tracks... " << endl;
291  return vector<Trajectory>();
292  }
293 
294 }
295 
296 
297 //
298 //
299 //
302  map<DetId, int> &hitMap) const {
303 
304  LogTrace(theCategory) << " GlobalMuonRefitter::checkMuonHits " << endl;
305 
306  float coneSize = 20.0;
307 
308  // loop through all muon hits and calculate the maximum # of hits in each chamber
309  for (ConstRecHitContainer::const_iterator imrh = all.begin(); imrh != all.end(); imrh++ ) {
310 
311  if ( (*imrh != 0 ) && !(*imrh)->isValid() ) continue;
312 
313  int detRecHits = 0;
314  MuonRecHitContainer dRecHits;
315 
316  DetId id = (*imrh)->geographicalId();
317  DetId chamberId;
318 
319  // Skip tracker hits
320  if (id.det()!=DetId::Muon) continue;
321 
322  if ( id.subdetId() == MuonSubdetId::DT ) {
323  DTChamberId did(id.rawId());
324  chamberId=did;
325 
326  if ((*imrh)->recHits().size()>1) {
327  std::vector <const TrackingRecHit*> hits2d = (*imrh)->recHits();
328  for (std::vector <const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d!= hits2d.end(); hit2d++) {
329  if ((*imrh)->recHits().size()>1) {
330  std::vector <const TrackingRecHit*> hits1d = (*hit2d)->recHits();
331  for (std::vector <const TrackingRecHit*>::const_iterator hit1d = hits1d.begin(); hit1d!= hits1d.end(); hit1d++) {
332  DetId id1 = (*hit1d)->geographicalId();
333  DTLayerId lid(id1.rawId());
334  // Get the 1d DT RechHits from this layer
335  DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
336  int layerHits=0;
337  for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
338  double rhitDistance = fabs(ir->localPosition().x()-(**hit1d).localPosition().x());
339  if ( rhitDistance < coneSize ) layerHits++;
340  LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**hit1d).localPosition()
341  << " Distance: " << rhitDistance << " recHits: " << layerHits << " SL: " << lid.superLayer() << endl;
342  }
343  if (layerHits>detRecHits) detRecHits=layerHits;
344  }
345  }
346  }
347 
348  } else {
349  DTLayerId lid(id.rawId());
350 
351  // Get the 1d DT RechHits from this layer
352  DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
353 
354  for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
355  double rhitDistance = fabs(ir->localPosition().x()-(**imrh).localPosition().x());
356  if ( rhitDistance < coneSize ) detRecHits++;
357  LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**imrh).localPosition()
358  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
359  }
360  }
361  }// end of if DT
362  else if ( id.subdetId() == MuonSubdetId::CSC ) {
363  CSCDetId did(id.rawId());
364  chamberId=did.chamberId();
365 
366  if ((*imrh)->recHits().size()>1) {
367  std::vector <const TrackingRecHit*> hits2d = (*imrh)->recHits();
368  for (std::vector <const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d!= hits2d.end(); hit2d++) {
369  DetId id1 = (*hit2d)->geographicalId();
370  CSCDetId lid(id1.rawId());
371 
372  // Get the CSC Rechits from this layer
373  CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(lid);
374  int layerHits=0;
375 
376  for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
377  double rhitDistance = (ir->localPosition()-(**hit2d).localPosition()).mag();
378  if ( rhitDistance < coneSize ) layerHits++;
379  LogTrace(theCategory) << ir->localPosition() << " " << (**hit2d).localPosition()
380  << " Distance: " << rhitDistance << " recHits: " << layerHits << endl;
381  }
382  if (layerHits>detRecHits) detRecHits=layerHits;
383  }
384  } else {
385  // Get the CSC Rechits from this layer
386  CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);
387 
388  for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
389  double rhitDistance = (ir->localPosition()-(**imrh).localPosition()).mag();
390  if ( rhitDistance < coneSize ) detRecHits++;
391  LogTrace(theCategory) << ir->localPosition() << " " << (**imrh).localPosition()
392  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
393  }
394  }
395  } //end of CSC if
396  else if ( id.subdetId() == MuonSubdetId::GEM ) {
397  GEMDetId did(id.rawId());
398  chamberId=did.chamberId();
399 
400  if ((*imrh)->recHits().size()>1) {
401  std::vector <const TrackingRecHit*> hits2d = (*imrh)->recHits();
402  for (std::vector <const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d!= hits2d.end(); hit2d++) {
403  DetId id1 = (*hit2d)->geographicalId();
404  GEMDetId lid(id1.rawId());
405 
406  // Get the GEM Rechits from this layer
407  GEMRecHitCollection::range dRecHits = theGEMRecHits->get(lid);
408  int layerHits=0;
409 
410  for (GEMRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
411  double rhitDistance = (ir->localPosition()-(**hit2d).localPosition()).mag();
412  if ( rhitDistance < coneSize ) layerHits++;
413  LogTrace(theCategory) << ir->localPosition() << " " << (**hit2d).localPosition()
414  << " Distance: " << rhitDistance << " recHits: " << layerHits << endl;
415  }
416  if (layerHits>detRecHits) detRecHits=layerHits;
417  }
418  } else {
419  // Get the GEM Rechits from this layer
420  GEMRecHitCollection::range dRecHits = theGEMRecHits->get(did);
421 
422  for (GEMRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
423  double rhitDistance = (ir->localPosition()-(**imrh).localPosition()).mag();
424  if ( rhitDistance < coneSize ) detRecHits++;
425  LogTrace(theCategory) << ir->localPosition() << " " << (**imrh).localPosition()
426  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
427  }
428  }
429  }
430  else {
431  if ( id.subdetId() != MuonSubdetId::RPC ) LogError(theCategory)<<" Wrong Hit Type ";
432  continue;
433  }
434 
435  map<DetId,int>::iterator imap=hitMap.find(chamberId);
436  if (imap!=hitMap.end()) {
437  if (detRecHits>imap->second) imap->second=detRecHits;
438  } else hitMap[chamberId]=detRecHits;
439 
440  } // end of loop over muon rechits
441 
442  for (map<DetId,int>::iterator imap=hitMap.begin(); imap!=hitMap.end(); imap++ )
443  LogTrace(theCategory) << " Station " << imap->first.rawId() << ": " << imap->second <<endl;
444 
445  LogTrace(theCategory) << "CheckMuonHits: "<<all.size();
446 
447  // check order of muon measurements
448  if ( (all.size() > 1) &&
449  ( all.front()->globalPosition().mag() >
450  all.back()->globalPosition().mag() ) ) {
451  LogTrace(theCategory)<< "reverse order: ";
452  stable_sort(all.begin(),all.end(),RecHitLessByDet(alongMomentum));
453  }
454 }
455 
456 
457 //
458 // Get the hits from the first muon station (containing hits)
459 //
462  ConstRecHitContainer& first) const {
463 
464  LogTrace(theCategory) << " GlobalMuonRefitter::getFirstHits\nall rechits length:" << all.size() << endl;
465  first.clear();
466 
467  int station_to_keep = 999;
468  vector<int> stations;
469  for (ConstRecHitContainer::const_iterator ihit = all.begin(); ihit != all.end(); ++ihit) {
470 
471  int station = 0;
472  bool use_it = true;
473  DetId id = (*ihit)->geographicalId();
474  unsigned raw_id = id.rawId();
475  if (!(*ihit)->isValid()) station = -1;
476  else {
477  if (id.det() == DetId::Muon) {
478  switch (id.subdetId()) {
479  case MuonSubdetId::DT: station = DTChamberId(raw_id).station(); break;
480  case MuonSubdetId::CSC: station = CSCDetId(raw_id).station(); break;
481  case MuonSubdetId::GEM: station = GEMDetId(raw_id).station(); break;
482  case MuonSubdetId::RPC: station = RPCDetId(raw_id).station(); use_it = false; break;
483  }
484  }
485  }
486 
487 
488  if (use_it && station > 0 && station < station_to_keep) station_to_keep = station;
489  stations.push_back(station);
490  LogTrace(theCategory) << "rawId: " << raw_id << " station = " << station << " station_to_keep is now " << station_to_keep;
491  }
492 
493  if (station_to_keep <= 0 || station_to_keep > 4 || stations.size() != all.size())
494  LogInfo(theCategory) << "failed to getFirstHits (all muon hits are outliers/bad ?)! station_to_keep = "
495  << station_to_keep << " stations.size " << stations.size() << " all.size " << all.size();
496 
497  for (unsigned i = 0; i < stations.size(); ++i)
498  if (stations[i] >= 0 && stations[i] <= station_to_keep) first.push_back(all[i]);
499 
500  return;
501 }
502 
503 
504 //
505 // select muon hits compatible with trajectory;
506 // check hits in chambers with showers
507 //
510  const map<DetId, int> &hitMap) const {
511 
512  ConstRecHitContainer muonRecHits;
513  const double globalChi2Cut = 200.0;
514 
515  vector<TrajectoryMeasurement> muonMeasurements = traj.measurements();
516 
517  // loop through all muon hits and skip hits with bad chi2 in chambers with high occupancy
518  for (std::vector<TrajectoryMeasurement>::const_iterator im = muonMeasurements.begin(); im != muonMeasurements.end(); im++ ) {
519 
520  if ( !(*im).recHit()->isValid() ) continue;
521  if ( (*im).recHit()->det()->geographicalId().det() != DetId::Muon ) {
522  // if ( ( chi2ndf < globalChi2Cut ) )
523  muonRecHits.push_back((*im).recHit());
524  continue;
525  }
526  const MuonTransientTrackingRecHit* immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*im).recHit().get());
527 
528  DetId id = immrh->geographicalId();
529  DetId chamberId;
530  int threshold = 0;
531  double chi2Cut = 0.0;
532 
533  // get station of hit if it is in DT
534  if ( (*immrh).isDT() ) {
535  DTChamberId did(id.rawId());
536  chamberId = did;
537  threshold = theHitThreshold;
538  chi2Cut = theDTChi2Cut;
539  }
540  // get station of hit if it is in CSC
541  else if ( (*immrh).isCSC() ) {
542  CSCDetId did(id.rawId());
543  chamberId = did.chamberId();
544  threshold = theHitThreshold;
545  chi2Cut = theCSCChi2Cut;
546  }
547  // get station of hit if it is in GEM
548  else if ( (*immrh).isGEM() ) {
549  GEMDetId did(id.rawId());
550  chamberId = did.chamberId();
551  threshold = theHitThreshold;
552  chi2Cut = theGEMChi2Cut;
553  }
554  // get station of hit if it is in RPC
555  else if ( (*immrh).isRPC() ) {
556  RPCDetId rpcid(id.rawId());
557  chamberId = rpcid;
558  threshold = theHitThreshold;
559  chi2Cut = theRPCChi2Cut;
560  } else
561  continue;
562 
563  double chi2ndf = (*im).estimate()/(*im).recHit()->dimension();
564 
565  bool keep = true;
566  map<DetId,int>::const_iterator imap=hitMap.find(chamberId);
567  if ( imap!=hitMap.end() )
568  if (imap->second>threshold) keep = false;
569 
570  if ( (keep || (chi2ndf<chi2Cut)) && (chi2ndf<globalChi2Cut) ) {
571  muonRecHits.push_back((*im).recHit());
572  } else {
574  << "Skip hit: " << id.rawId() << " chi2="
575  << chi2ndf << " ( threshold: " << chi2Cut << ") Det: "
576  << imap->second << endl;
577  }
578  }
579 
580  // check order of rechits
581  reverse(muonRecHits.begin(),muonRecHits.end());
582  return muonRecHits;
583 }
584 
585 
586 //
587 // print RecHits
588 //
590 
591  LogTrace(theCategory) << "Used RecHits: " << hits.size();
592  for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
593  if ( !(*ir)->isValid() ) {
594  LogTrace(theCategory) << "invalid RecHit";
595  continue;
596  }
597 
598  const GlobalPoint& pos = (*ir)->globalPosition();
599 
601  << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y())
602  << " z = " << pos.z()
603  << " dimension = " << (*ir)->dimension()
604  << " det = " << (*ir)->det()->geographicalId().det()
605  << " subdet = " << (*ir)->det()->subDetector()
606  << " raw id = " << (*ir)->det()->geographicalId().rawId();
607  }
608 
609 }
610 
611 
612 //
613 // add Trajectory* to TrackCand if not already present
614 //
617 
618  if (!recHits.empty()){
619  ConstRecHitContainer::const_iterator frontHit = recHits.begin();
620  ConstRecHitContainer::const_iterator backHit = recHits.end() - 1;
621  while( !(*frontHit)->isValid() && frontHit != backHit) {frontHit++;}
622  while( !(*backHit)->isValid() && backHit != frontHit) {backHit--;}
623 
624  double rFirst = (*frontHit)->globalPosition().mag();
625  double rLast = (*backHit) ->globalPosition().mag();
626 
627  if(rFirst < rLast) return insideOut;
628  else if(rFirst > rLast) return outsideIn;
629  else {
630  LogError(theCategory) << "Impossible determine the rechits order" <<endl;
631  return undetermined;
632  }
633  } else {
634  LogError(theCategory) << "Impossible determine the rechits order" <<endl;
635  return undetermined;
636  }
637 }
638 
639 
640 //
641 // Convert Tracks into Trajectories with a given set of hits
642 //
643 vector<Trajectory> GlobalMuonRefitter::transform(const reco::Track& newTrack,
644  const reco::TransientTrack track,
645  const TransientTrackingRecHit::ConstRecHitContainer& urecHitsForReFit) const {
646 
647  TransientTrackingRecHit::ConstRecHitContainer recHitsForReFit = urecHitsForReFit;
648  LogTrace(theCategory) << "GlobalMuonRefitter::transform: " << recHitsForReFit.size() << " hits:";
649  printHits(recHitsForReFit);
650 
651  if(recHitsForReFit.size() < 2) return vector<Trajectory>();
652 
653  // Check the order of the rechits
654  RefitDirection recHitsOrder = checkRecHitsOrdering(recHitsForReFit);
655 
656  LogTrace(theCategory) << "checkRecHitsOrdering() returned " << recHitsOrder
657  << ", theRefitDirection is " << theRefitDirection
658  << " (insideOut == " << insideOut << ", outsideIn == " << outsideIn << ")";
659 
660  // Reverse the order in the case of inconsistency between the fit direction and the rechit order
661  if(theRefitDirection != recHitsOrder) reverse(recHitsForReFit.begin(),recHitsForReFit.end());
662 
663  // Even though we checked the rechits' ordering above, we may have
664  // already flipped them elsewhere (getFirstHits() is such a
665  // culprit). Use the global positions of the states and the desired
666  // refit direction to find the starting TSOS.
667  TrajectoryStateOnSurface firstTSOS, lastTSOS;
668  unsigned int innerId; //UNUSED: outerId;
669  bool order_swapped = track.outermostMeasurementState().globalPosition().mag() < track.innermostMeasurementState().globalPosition().mag();
670  bool inner_is_first;
671  LogTrace(theCategory) << "order swapped? " << order_swapped;
672 
673  // Fill the starting state, depending on the ordering above.
674  if ((theRefitDirection == insideOut && !order_swapped) || (theRefitDirection == outsideIn && order_swapped)) {
675  innerId = newTrack.innerDetId();
676  //UNUSED: outerId = newTrack.outerDetId();
677  firstTSOS = track.innermostMeasurementState();
678  lastTSOS = track.outermostMeasurementState();
679  inner_is_first = true;
680  }
681  else {
682  innerId = newTrack.outerDetId();
683  //UNUSED: outerId = newTrack.innerDetId();
684  firstTSOS = track.outermostMeasurementState();
685  lastTSOS = track.innermostMeasurementState();
686  inner_is_first = false;
687  }
688 
689  LogTrace(theCategory) << "firstTSOS: inner_is_first? " << inner_is_first
690  << " globalPosition is " << firstTSOS.globalPosition()
691  << " innerId is " << innerId;
692 
693  if(!firstTSOS.isValid()){
694  LogWarning(theCategory) << "Error wrong initial state!" << endl;
695  return vector<Trajectory>();
696  }
697 
698  firstTSOS.rescaleError(theRescaleErrorFactor);
699 
700  // This is the only way to get a TrajectorySeed with settable propagation direction
701  PTrajectoryStateOnDet garbage1;
703  PropagationDirection propDir =
704  (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
705 
706  // These lines cause the code to ignore completely what was set
707  // above, and force propDir for tracks from collisions!
708 // if(propDir == alongMomentum && theRefitDirection == outsideIn) propDir=oppositeToMomentum;
709 // if(propDir == oppositeToMomentum && theRefitDirection == insideOut) propDir=alongMomentum;
710 
711  const TrajectoryStateOnSurface& tsosForDir = inner_is_first ? lastTSOS : firstTSOS;
712  propDir = (tsosForDir.globalPosition().basicVector().dot(tsosForDir.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
713  LogTrace(theCategory) << "propDir based on firstTSOS x dot p is " << propDir
714  << " (alongMomentum == " << alongMomentum << ", oppositeToMomentum == " << oppositeToMomentum << ")";
715 
716  // Additional propagation diretcion determination logic for cosmic muons
717  if (theCosmicFlag) {
718  PropagationDirection propDir_first = (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
719  PropagationDirection propDir_last = (lastTSOS .globalPosition().basicVector().dot(lastTSOS .globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
720  LogTrace(theCategory) << "propDir_first " << propDir_first << ", propdir_last " << propDir_last
721  << " : they " << (propDir_first == propDir_last ? "agree" : "disagree");
722 
723  int y_count = 0;
724  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator it = recHitsForReFit.begin(); it != recHitsForReFit.end(); ++it) {
725  if ((*it)->globalPosition().y() > 0) ++y_count;
726  else --y_count;
727  }
728 
729  PropagationDirection propDir_ycount = alongMomentum;
730  if (y_count > 0) {
731  if (theRefitDirection == insideOut) propDir_ycount = oppositeToMomentum;
732  else if (theRefitDirection == outsideIn) propDir_ycount = alongMomentum;
733  }
734  else {
735  if (theRefitDirection == insideOut) propDir_ycount = alongMomentum;
736  else if (theRefitDirection == outsideIn) propDir_ycount = oppositeToMomentum;
737  }
738 
739  LogTrace(theCategory) << "y_count = " << y_count
740  << "; based on geometrically-outermost TSOS, propDir is " << propDir << ": "
741  << (propDir == propDir_ycount ? "agrees" : "disagrees")
742  << " with ycount determination";
743 
744  if (propDir_first != propDir_last) {
745  LogTrace(theCategory) << "since first/last disagreed, using y_count propDir";
746  propDir = propDir_ycount;
747  }
748  }
749 
750  TrajectorySeed seed(garbage1,garbage2,propDir);
751 
752  if(recHitsForReFit.front()->geographicalId() != DetId(innerId)){
753  LogDebug(theCategory)<<"Propagation occured"<<endl;
754  LogTrace(theCategory) << "propagating firstTSOS at " << firstTSOS.globalPosition()
755  << " to first rechit with surface pos " << recHitsForReFit.front()->det()->surface().toGlobal(LocalPoint(0,0,0));
756  firstTSOS = theService->propagator(thePropagatorName)->propagate(firstTSOS, recHitsForReFit.front()->det()->surface());
757  if(!firstTSOS.isValid()){
758  LogDebug(theCategory)<<"Propagation error!"<<endl;
759  return vector<Trajectory>();
760  }
761  }
762 
763 /*
764  cout << " GlobalMuonRefitter : theFitter " << propDir << endl;
765  cout << " First TSOS: "
766  << firstTSOS.globalPosition() << " p="
767  << firstTSOS.globalMomentum() << " = "
768  << firstTSOS.globalMomentum().mag() << endl;
769 
770  cout << " Starting seed: "
771  << " nHits= " << seed.nHits()
772  << " tsos: "
773  << seed.startingState().parameters().position() << " p="
774  << seed.startingState().parameters().momentum() << endl;
775 
776  cout << " RecHits: "
777  << recHitsForReFit.size() << endl;
778 */
779 
780  vector<Trajectory> trajectories = theFitter->fit(seed,recHitsForReFit,firstTSOS);
781 
782  if(trajectories.empty()){
783  LogDebug(theCategory) << "No Track refitted!" << endl;
784  return vector<Trajectory>();
785  }
786  return trajectories;
787 }
788 
789 
790 //
791 // Remove Selected Station Rec Hits
792 //
794  const TrackerTopology *tTopo) const
795 {
797  ConstRecHitContainer::const_iterator it = hits.begin();
798  for (; it!=hits.end(); it++) {
799 
800  DetId id = (*it)->geographicalId();
801 
802  //Check that this is a Muon hit that we're toying with -- else pass on this because the hacker is a moron / not careful
803 
804  if (id.det() == DetId::Tracker && theTrackerSkipSystem > 0) {
805  int layer = -999;
806  int disk = -999;
807  int wheel = -999;
808  if ( id.subdetId() == theTrackerSkipSystem){
809  // continue; //caveat that just removes the whole system from refitting
810 
811  if (theTrackerSkipSystem == PXB) {
812 
813  layer = tTopo->pxbLayer(id);
814  }
815  if (theTrackerSkipSystem == TIB) {
816 
817  layer = tTopo->tibLayer(id);
818  }
819 
820  if (theTrackerSkipSystem == TOB) {
821 
822  layer = tTopo->tobLayer(id);
823  }
824  if (theTrackerSkipSystem == PXF) {
825 
826  disk = tTopo->pxfDisk(id);
827  }
828  if (theTrackerSkipSystem == TID) {
829 
830  wheel = tTopo->tidWheel(id);
831  }
832  if (theTrackerSkipSystem == TEC) {
833 
834  wheel = tTopo->tecWheel(id);
835  }
836  if (theTrackerSkipSection >= 0 && layer == theTrackerSkipSection) continue;
837  if (theTrackerSkipSection >= 0 && disk == theTrackerSkipSection) continue;
838  if (theTrackerSkipSection >= 0 && wheel == theTrackerSkipSection) continue;
839  }
840  }
841 
842  if (id.det() == DetId::Muon && theSkipStation) {
843  int station = -999;
844  //UNUSED: int wheel = -999;
845  if ( id.subdetId() == MuonSubdetId::DT ) {
846  DTChamberId did(id.rawId());
847  station = did.station();
848  //UNUSED: wheel = did.wheel();
849  } else if ( id.subdetId() == MuonSubdetId::CSC ) {
850  CSCDetId did(id.rawId());
851  station = did.station();
852  } else if ( id.subdetId() == MuonSubdetId::GEM ) {
853  GEMDetId did(id.rawId());
854  station = did.station();
855  } else if ( id.subdetId() == MuonSubdetId::RPC ) {
856  RPCDetId rpcid(id.rawId());
857  station = rpcid.station();
858  }
859  if(station == theSkipStation) continue;
860  }
861  results.push_back(*it);
862  }
863  return results;
864 }
865 
#define LogDebug(id)
std::string theMuonRecHitBuilderName
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void printHits(const ConstRecHitContainer &) const
print all RecHits of a trajectory
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
edm::Handle< DTRecHitCollection > theDTRecHits
void setProd(const edm::Handle< DTRecSegment4DCollection > &DTSegProd, const edm::Handle< CSCSegmentCollection > &CSCSegProd)
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
const MuonServiceProxy * theService
unsigned int tibLayer(const DetId &id) const
RefitDirection theRefitDirection
edm::ESHandle< TransientTrackingRecHitBuilder > theTrackerRecHitBuilder
edm::Handle< CSCSegmentCollection > CSCSegments
std::string thePropagatorName
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
unsigned int pxfDisk(const DetId &id) const
static const int GEM
Definition: MuonSubdetId.h:15
T y() const
Definition: PV3DBase.h:63
edm::Handle< GEMRecHitCollection > theGEMRecHits
GlobalPoint globalPosition() const
void setServices(const edm::EventSetup &)
set the services needed by the TrackTransformer
unsigned int tidWheel(const DetId &id) const
void CopyFrom(const DYTInfo &)
copy from another DYTInfo
Definition: DYTInfo.cc:15
PropagationDirection
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
edm::EDGetTokenT< CSCSegmentCollection > CSCSegmentsToken
std::unique_ptr< TrajectoryFitter > theFitter
edm::ESHandle< TransientTrackingRecHitBuilder > theMuonRecHitBuilder
void checkMuonHits(const reco::Track &, ConstRecHitContainer &, std::map< DetId, int > &) const
check muon RecHits, calculate chamber occupancy and select hits to be used in the final fit ...
TrajectoryStateOnSurface innermostMeasurementState() const
std::vector< int > theDYTthrs
GEMDetId chamberId() const
Return the corresponding ChamberId.
Definition: GEMDetId.h:86
void getFirstHits(const reco::Track &, ConstRecHitContainer &, ConstRecHitContainer &) const
get the RecHits in the tracker and the first muon chamber with hits
const edm::Event * theEvent
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
DataContainer const & measurements() const
Definition: Trajectory.h:203
const int keep
static const int CSC
Definition: MuonSubdetId.h:13
T mag() const
Definition: PV3DBase.h:67
edm::Handle< DTRecSegment4DCollection > all4DSegments
ConstRecHitContainer selectMuonHits(const Trajectory &, const std::map< DetId, int > &) const
select muon hits compatible with trajectory; check hits in chambers with showers
ConstRecHitContainer getRidOfSelectStationHits(const ConstRecHitContainer &hits, const TrackerTopology *tTopo) const
T sqrt(T t)
Definition: SSEVec.h:48
double pt() const
track transverse momentum
Definition: TrackBase.h:608
T z() const
Definition: PV3DBase.h:64
MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Definition: Track.h:94
int station() const
Station id : the station is the pair of chambers at same disk.
Definition: GEMDetId.h:64
CSCDetId chamberId() const
Definition: CSCDetId.h:66
edm::Handle< CSCRecHit2DCollection > theCSCRecHits
RefitDirection checkRecHitsOrdering(const ConstRecHitContainer &) const
edm::EDGetTokenT< DTRecHitCollection > theDTRecHitToken
edm::EDGetTokenT< CSCRecHit2DCollection > theCSCRecHitToken
TrajectoryStateOnSurface outermostMeasurementState() const
TransientTrackingRecHit::ConstRecHitContainer filter(const Trajectory &)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
#define LogTrace(id)
edm::InputTag theDTRecHitLabel
std::vector< ConstRecHitPointer > ConstRecHitContainer
unsigned int pxbLayer(const DetId &id) const
edm::InputTag theGEMRecHitLabel
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
Definition: DetId.h:18
GlobalMuonRefitter(const edm::ParameterSet &, const MuonServiceProxy *, edm::ConsumesCollector &)
constructor with Parameter Set and MuonServiceProxy
edm::EDGetTokenT< DTRecSegment4DCollection > all4DSegmentsToken
const T & get() const
Definition: EventSetup.h:56
T const * product() const
Definition: ESHandle.h:86
reco::DYTInfo getDYTInfo()
reco::DYTInfo * dytInfo
GlobalVector globalMomentum() const
static const int RPC
Definition: MuonSubdetId.h:14
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
int station() const
Definition: CSCDetId.h:99
static const int DT
Definition: MuonSubdetId.h:12
virtual ~GlobalMuonRefitter()
destructor
DetId geographicalId() const
unsigned long long theCacheId_TRH
int station() const
Return the station number.
Definition: DTChamberId.h:51
T x() const
Definition: PV3DBase.h:62
std::string theTrackerRecHitBuilderName
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:56
unsigned int tecWheel(const DetId &id) const
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
Definition: Track.h:99
void setThr(const std::vector< int > &)
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
std::vector< Trajectory > refit(const reco::Track &globalTrack, const int theMuonHitsOption, const TrackerTopology *tTopo) const
build combined trajectory from sta Track and tracker RecHits
unsigned int tobLayer(const DetId &id) const
TrackingRecHitCollection::base::const_iterator trackingRecHit_iterator
iterator over a vector of reference to TrackingRecHit in the same collection
edm::InputTag theCSCRecHitLabel
edm::EDGetTokenT< GEMRecHitCollection > theGEMRecHitToken
std::vector< Trajectory > transform(const reco::Track &newTrack, const reco::TransientTrack track, const TransientTrackingRecHit::ConstRecHitContainer &recHitsForReFit) const
refit the track with a new set of RecHits
T dot(const Basic3DVector &rh) const
Scalar product, or &quot;dot&quot; product, with a vector of same type.
int station() const
Definition: RPCDetId.h:96