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