CMS 3D CMS Logo

CandidateSimMuonMatcher.cc
Go to the documentation of this file.
1 /*
2  * CandidateSimMuonMatcher.cc
3  *
4  * Created on: Dec 14, 2020
5  * Author: kbunkow
6  */
7 
10 
14 
20 
22 
23 #include "TFile.h"
24 #include "TH1D.h"
25 
26 //#include "CLHEP/Units/GlobalPhysicalConstants.h"
27 
28 double hwGmtPhiToGlobalPhi(int phi) {
29  double phiGmtUnit = 2. * M_PI / 576.;
30  return phi * phiGmtUnit;
31 }
32 
33 double foldPhi(double phi) {
34  if (phi > M_PI)
35  return (phi - 2 * M_PI);
36  else if (phi < -M_PI)
37  return (phi + 2 * M_PI);
38 
39  return phi;
40 }
41 
43  const edm::ParameterSet& edmCfg,
44  const OMTFConfiguration* omtfConfig,
47  : omtfConfig(omtfConfig),
48  edmCfg(edmCfg),
49  magneticFieldEsToken(magneticFieldEsToken),
50  propagatorEsToken(propagatorEsToken) {
51  std::string muonMatcherFileName = edmCfg.getParameter<edm::FileInPath>("muonMatcherFile").fullPath();
52  TFile inFile(muonMatcherFileName.c_str());
53  edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: using muonMatcherFileName "
54  << muonMatcherFileName << std::endl;
55 
56  deltaPhiPropCandMean = (TH1D*)inFile.Get("deltaPhiPropCandMean");
57  deltaPhiPropCandStdDev = (TH1D*)inFile.Get("deltaPhiPropCandStdDev");
58 }
59 
61 
63  //TODO use edm::ESWatcher<MagneticField> magneticFieldRecordWatcher;
66 }
67 
69 
71  l1t::tftype mtfType,
72  const std::shared_ptr<OMTFinput>& input,
73  const AlgoMuons& algoCandidates,
74  const AlgoMuons& gbCandidates,
75  const std::vector<l1t::RegionalMuonCand>& candMuons) {
76  //debug
77  /*
78  unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType);
79  for (auto& gbCandidate : gbCandidates) {
80  if (gbCandidate->getPt() > 0) {
81  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::observeProcesorEmulation procIndx" << procIndx<" "<< *gbCandidate << endl;
82  this->gbCandidates.emplace_back(gbCandidate);
83  }
84  }*/
85 }
86 
88  if (abs(simTrack.type()) == 13 || abs(simTrack.type()) == 1000015) { //|| tpPtr->pt() > 20 //todo 1000015 is stau
89  //only muons
90  } else
91  return false;
92 
93  //in the overlap, the propagation of muons with pt less then ~3.2 fails - the actual threshold depends slightly on eta,
94  if (simTrack.momentum().pt() < 2.5)
95  return false;
96 
97  LogTrace("l1tOmtfEventPrint") << "simTrackIsMuonInOmtf, simTrack type " << std::setw(3) << simTrack.type() << " pt "
98  << std::setw(9) << simTrack.momentum().pt() << " eta " << std::setw(9)
99  << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi()
100  << std::endl;
101 
102  //higher margin for matching must be used than actual OMTF region (i.e. 0.82 - 1.24),
103  //otherwise many candidates are marked as ghosts
104  //if( (fabs(simTrack.momentum().eta()) >= 0.82 ) && (fabs(simTrack.momentum().eta()) <= 1.24) ) {
105  if ((fabs(simTrack.momentum().eta()) >= 0.72) && (fabs(simTrack.momentum().eta()) <= 1.3)) {
106  } else
107  return false;
108 
109  return true;
110 }
111 
113  if (simTrack.eventId().bunchCrossing() != 0)
114  return false;
115 
117 }
118 
119 bool trackingParticleIsMuonInOmtfBx0(const TrackingParticle& trackingParticle) {
120  /*if(trackingParticle.eventId().event() != 0)
121  LogTrace("l1tOmtfEventPrint") <<"trackingParticleIsMuonInOmtfBx0, pdgId "<<std::setw(3)<<trackingParticle.pdgId()<<" pt "<<std::setw(9)<<trackingParticle.pt()
122  <<" eta "<<std::setw(9)<<trackingParticle.momentum().eta()<<" phi "<<std::setw(9)<<trackingParticle.momentum().phi()<<" event "<<trackingParticle.eventId().event()
123  <<" bx "<<trackingParticle.eventId().bunchCrossing()<<" eventNot0"<<std::endl;*/
124 
125  if (trackingParticle.eventId().bunchCrossing() != 0)
126  return false;
127 
128  if (abs(trackingParticle.pdgId()) == 13 || abs(trackingParticle.pdgId()) == 1000015) {
129  // 1000015 is stau, todo use other selection if needed
130  //only muons
131  } else
132  return false;
133 
134  //in the overlap, the propagation of muons with pt less then ~3.2 fails, the actual threshold depends slightly on eta,
135  if (trackingParticle.pt() < 2.5)
136  return false;
137 
138  if (trackingParticle.parentVertex().isNonnull())
139  LogTrace("l1tOmtfEventPrint") << "trackingParticleIsMuonInOmtfBx0, pdgId " << std::setw(3)
140  << trackingParticle.pdgId() << " pt " << std::setw(9) << trackingParticle.pt()
141  << " eta " << std::setw(9) << trackingParticle.momentum().eta() << " phi "
142  << std::setw(9) << trackingParticle.momentum().phi() << " event "
143  << trackingParticle.eventId().event() << " trackId "
144  << trackingParticle.g4Tracks().at(0).trackId() << " parentVertex Rho "
145  << trackingParticle.parentVertex()->position().Rho() << " eta "
146  << trackingParticle.parentVertex()->position().eta() << " phi "
147  << trackingParticle.parentVertex()->position().phi() << std::endl;
148  else
149  LogTrace("l1tOmtfEventPrint") << "trackingParticleIsMuonInOmtfBx0, pdgId " << std::setw(3)
150  << trackingParticle.pdgId() << " pt " << std::setw(9) << trackingParticle.pt()
151  << " eta " << std::setw(9) << trackingParticle.momentum().eta() << " phi "
152  << std::setw(9) << trackingParticle.momentum().phi() << " trackId "
153  << trackingParticle.g4Tracks().at(0).trackId();
154 
155  //higher margin for matching must be used than actual OMTF region (i.e. 0.82 - 1.24),
156  //otherwise many candidates are marked as ghosts
157  //if( (fabs(simTrack.momentum().eta()) >= 0.82 ) && (fabs(trackingParticle.momentum().eta()) <= 1.24) ) {
158  if ((fabs(trackingParticle.momentum().eta()) >= 0.72) && (fabs(trackingParticle.momentum().eta()) <= 1.3)) {
159  } else
160  return false;
161 
162  return true;
163 }
164 
166  if (trackingParticle.eventId().event() != 0)
167  return false;
168 
169  return trackingParticleIsMuonInOmtfBx0(trackingParticle);
170 }
171 
173  std::unique_ptr<l1t::RegionalMuonCandBxCollection>& finalCandidates) {
174  AlgoMuons ghostBustedProcMuons;
175  std::vector<const l1t::RegionalMuonCand*> ghostBustedRegionalCands =
176  CandidateSimMuonMatcher::ghostBust(finalCandidates.get(), gbCandidates, ghostBustedProcMuons);
177 
178  matchingResults.clear();
179  if (edmCfg.exists("simTracksTag")) {
181  event.getByLabel(edmCfg.getParameter<edm::InputTag>("simTracksTag"), simTraksHandle);
182 
184  event.getByLabel(edmCfg.getParameter<edm::InputTag>("simVertexesTag"), simVertices);
185  LogTrace("l1tOmtfEventPrint") << "simTraksHandle size " << simTraksHandle.product()->size() << std::endl;
186 
187  //TODO use other simTrackFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
188  std::function<bool(const SimTrack&)> const& simTrackFilter = simTrackIsMuonInOmtfBx0;
189 
191  ghostBustedRegionalCands, ghostBustedProcMuons, simTraksHandle.product(), simVertices.product(), simTrackFilter);
192 
193  } else if (edmCfg.exists("trackingParticleTag")) {
194  edm::Handle<TrackingParticleCollection> trackingParticleHandle;
195  event.getByLabel(edmCfg.getParameter<edm::InputTag>("trackingParticleTag"), trackingParticleHandle);
196  LogTrace("l1tOmtfEventPrint") << "trackingParticleHandle size " << trackingParticleHandle.product()->size()
197  << std::endl;
198 
199  //TODO use other trackParticleFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
200  std::function<bool(const TrackingParticle&)> trackParticleFilter = trackingParticleIsMuonInOmtfBx0;
202  match(ghostBustedRegionalCands, ghostBustedProcMuons, trackingParticleHandle.product(), trackParticleFilter);
203  }
204 }
205 
207 
208 std::vector<const l1t::RegionalMuonCand*> CandidateSimMuonMatcher::ghostBust(
209  const l1t::RegionalMuonCandBxCollection* mtfCands, const AlgoMuons& gbCandidates, AlgoMuons& ghostBustedProcMuons) {
210  if (gbCandidates.size() != mtfCands->size()) {
211  edm::LogError("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust(): gbCandidates.size() "
212  << gbCandidates.size() << " != resultGbCandidates.size() " << mtfCands->size();
213  throw cms::Exception("gbCandidates.size() != mtfCands->size()");
214  }
215 
216  boost::dynamic_bitset<> isKilled(mtfCands->size(0), false);
217 
218  for (unsigned int i1 = 0; i1 < mtfCands->size(0); ++i1) {
219  for (unsigned int i2 = i1 + 1; i2 < mtfCands->size(0); ++i2) {
220  auto& mtfCand1 = mtfCands->at(0, i1);
221  auto& mtfCand2 = mtfCands->at(0, i2);
222 
223  if (abs(mtfCand1.hwEta() - mtfCand2.hwEta()) < (0.3 / 0.010875)) {
225  mtfCand1.hwPhi(), mtfCand1.trackFinderType(), mtfCand1.processor());
227  mtfCand2.hwPhi(), mtfCand2.trackFinderType(), mtfCand2.processor());
228 
229  //one can use the phi in radians like that:
230  //double globalPhi1 = hwGmtPhiToGlobalPhi(l1t::MicroGMTConfiguration::calcGlobalPhi( mtfCand1.hwPhi(), mtfCand1.trackFinderType(), mtfCand1.processor() ) );
231  //double globalPhi2 = hwGmtPhiToGlobalPhi(l1t::MicroGMTConfiguration::calcGlobalPhi( mtfCand2.hwPhi(), mtfCand2.trackFinderType(), mtfCand2.processor() ) );
232 
233  //0.0872664626 = 5 deg, i.e. the same window as in the OMTF ghost buster
234  if (abs(gloablHwPhi1 - gloablHwPhi2) < 8) {
235  if (mtfCand1.hwQual() > mtfCand2.hwQual()) {
236  isKilled[i2] = true;
237  } else
238  isKilled[i1] = true;
239  }
240  }
241  }
242  }
243 
244  std::vector<const l1t::RegionalMuonCand*> resultCands;
245 
246  for (unsigned int i1 = 0; i1 < mtfCands->size(0); ++i1) {
247  //dropping candidates with quality 0 !!!!!!!!!!!!!!!!!!!! fixme if not needed
248  if (!isKilled[i1] && mtfCands->at(0, i1).hwQual()) {
249  resultCands.push_back(&(mtfCands->at(0, i1)));
250  ghostBustedProcMuons.push_back(gbCandidates.at(i1));
251  }
252 
253  LogTrace("l1tOmtfEventPrint")
254  << "CandidateSimMuonMatcher::ghostBust\n regionalCand pt " << std::setw(3) << mtfCands->at(0, i1).hwPt()
255  << " qual " << std::setw(2) << mtfCands->at(0, i1).hwQual() << " proc " << std::setw(2)
256  << mtfCands->at(0, i1).processor() << " eta " << std::setw(4) << mtfCands->at(0, i1).hwEta() << " gloablEta "
257  << std::setw(8) << mtfCands->at(0, i1).hwEta() * 0.010875 << " hwPhi " << std::setw(3)
258  << mtfCands->at(0, i1).hwPhi() << " globalPhi " << std::setw(8)
260  mtfCands->at(0, i1).hwPhi(), mtfCands->at(0, i1).trackFinderType(), mtfCands->at(0, i1).processor()))
261  << " fireadLayers " << std::bitset<18>(mtfCands->at(0, i1).trackAddress().at(0)) << " isKilled "
262  << isKilled.test(i1) << std::endl;
263 
264  LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl;
265  }
266 
267  if (resultCands.size() >= 3)
268  LogTrace("l1tOmtfEventPrint") << " ghost !!!!!! " << std::endl;
269  LogTrace("l1tOmtfEventPrint") << std::endl;
270 
271  return resultCands;
272 }
273 
276  if (eta < -1.24) //negative endcap, RE2
278  new BoundDisk(GlobalPoint(0., 0., -790.), TkRotation<float>(), SimpleDiskBounds(300., 810., -10., 10.)));
279  else if (eta < 1.24) //barrel + overlap, 512.401cm is R of middle of the MB2
281  GlobalPoint(0., 0., 0.), TkRotation<float>(), SimpleCylinderBounds(512.401, 512.401, -900, 900)));
282  else
283  rpc = ReferenceCountingPointer<Surface>( //positive endcap, RE2
284  new BoundDisk(GlobalPoint(0., 0., 790.), TkRotation<float>(), SimpleDiskBounds(300., 810., -10., 10.)));
285 
286  TrajectoryStateOnSurface trackAtRPC = propagator->propagate(ftsStart, *rpc);
287  return trackAtRPC;
288 }
289 
291  int charge = simTrackPtr.type() > 0 ? -1 : 1; //works for muons
292 
293  GlobalVector p3GV(simTrackPtr.momentum().x(), simTrackPtr.momentum().y(), simTrackPtr.momentum().z());
294  GlobalPoint r3GP(simVertex.position().x(), simVertex.position().y(), simVertex.position().z());
295 
296  GlobalTrajectoryParameters tPars(r3GP, p3GV, charge, &*magField);
297 
298  return FreeTrajectoryState(tPars);
299 }
300 
302  int charge = trackingParticle.pdgId() > 0 ? -1 : 1; //works for muons
303 
304  GlobalVector p3GV(trackingParticle.momentum().x(), trackingParticle.momentum().y(), trackingParticle.momentum().z());
305  GlobalPoint r3GP(trackingParticle.vx(), trackingParticle.vy(), trackingParticle.vz());
306 
307  GlobalTrajectoryParameters tPars(r3GP, p3GV, charge, &*magField);
308 
309  return FreeTrajectoryState(tPars);
310 }
311 
315  int vtxInd = simTrack.vertIndex();
316  if (vtxInd < 0) {
317  std::cout << "Track with no vertex, defaulting to (0,0,0)" << std::endl;
318  } else {
319  simVertex = simVertices->at(vtxInd);
320  if (((int)simVertex.vertexId()) != vtxInd) {
321  std::cout << "simVertex.vertexId() != vtxInd !!!!!!!!!!!!!!!!!" << std::endl;
322  edm::LogImportant("l1tOmtfEventPrint") << "simVertex.vertexId() != vtxInd. simVertex.vertexId() "
323  << simVertex.vertexId() << " vtxInd " << vtxInd << " !!!!!!!!!!!!!!!!!";
324  }
325  }
326 
328 
329  TrajectoryStateOnSurface tsof = atStation2(ftsTrack, simTrack.momentum().eta()); //propagation
330 
331  return tsof;
332 }
333 
335  FreeTrajectoryState ftsTrack = simTrackToFts(trackingParticle);
336 
337  TrajectoryStateOnSurface tsof = atStation2(ftsTrack, trackingParticle.momentum().eta()); //propagation
338 
339  return tsof;
340 }
341 
342 float normal_pdf(float x, float m, float s) {
343  static const float inv_sqrt_2pi = 0.3989422804014327;
344  float a = (x - m) / s;
345 
346  return inv_sqrt_2pi / s * std::exp(-0.5 * a * a);
347 }
348 
350  const AlgoMuonPtr& procMuon,
351  const SimTrack& simTrack,
352  TrajectoryStateOnSurface& tsof) {
354 
355  double candGloablEta = muonCand->hwEta() * 0.010875;
356  if (abs(simTrack.momentum().eta() - candGloablEta) < 0.3) {
357  double candGlobalPhi = l1t::MicroGMTConfiguration::calcGlobalPhi(
358  muonCand->hwPhi(), muonCand->trackFinderType(), muonCand->processor());
359  candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi);
360 
361  if (candGlobalPhi > M_PI)
362  candGlobalPhi = candGlobalPhi - (2. * M_PI);
363 
364  result.deltaPhi = foldPhi(tsof.globalPosition().phi() - candGlobalPhi);
365  result.deltaEta = tsof.globalPosition().eta() - candGloablEta;
366 
367  result.propagatedPhi = tsof.globalPosition().phi();
368  result.propagatedEta = tsof.globalPosition().eta();
369 
370  double mean = 0;
371  double sigma = 1;
372  //if(!fillMean)
373  {
374  auto ptBin = deltaPhiPropCandMean->FindBin(simTrack.momentum().pt());
375  mean = deltaPhiPropCandMean->GetBinContent(ptBin);
376  sigma = deltaPhiPropCandStdDev->GetBinContent(ptBin);
377  }
378  result.matchingLikelihood = normal_pdf(result.deltaPhi, mean, sigma); //TODO temporary solution
379 
380  result.muonCand = muonCand;
381  result.procMuon = procMuon;
382 
383  double treshold = 6. * sigma;
384  if (simTrack.momentum().pt() > 20)
385  treshold = 7. * sigma;
386  if (simTrack.momentum().pt() > 100)
387  treshold = 20. * sigma;
388 
389  if (abs(result.deltaPhi - mean) < treshold)
391 
392  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << simTrack.type() << " pt "
393  << std::setw(8) << simTrack.momentum().pt() << " eta " << std::setw(8)
394  << simTrack.momentum().eta() << " phi " << std::setw(8) << simTrack.momentum().phi()
395  << " propagation eta " << std::setw(8) << tsof.globalPosition().eta() << " phi "
396  << tsof.globalPosition().phi() << "\n muonCand pt " << std::setw(8)
397  << muonCand->hwPt() << " candGloablEta " << std::setw(8) << candGloablEta
398  << " candGlobalPhi " << std::setw(8) << candGlobalPhi << " hwQual "
399  << muonCand->hwQual() << " deltaEta " << std::setw(8) << result.deltaEta
400  << " deltaPhi " << std::setw(8) << result.deltaPhi << " sigma " << std::setw(8)
401  << sigma << " Likelihood " << std::setw(8) << result.matchingLikelihood << " result "
402  << (short)result.result << std::endl;
403  }
404 
405  return result;
406 }
407 
409  const AlgoMuonPtr& procMuon,
410  const TrackingParticle& trackingParticle,
411  TrajectoryStateOnSurface& tsof) {
412  MatchingResult result(trackingParticle);
413 
414  double candGloablEta = muonCand->hwEta() * 0.010875;
415  if (abs(trackingParticle.momentum().eta() - candGloablEta) < 0.3) {
416  double candGlobalPhi = l1t::MicroGMTConfiguration::calcGlobalPhi(
417  muonCand->hwPhi(), muonCand->trackFinderType(), muonCand->processor());
418  candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi);
419 
420  if (candGlobalPhi > M_PI)
421  candGlobalPhi = candGlobalPhi - (2. * M_PI);
422 
423  result.deltaPhi = foldPhi(tsof.globalPosition().phi() - candGlobalPhi);
424  result.deltaEta = tsof.globalPosition().eta() - candGloablEta;
425 
426  result.propagatedPhi = tsof.globalPosition().phi();
427  result.propagatedEta = tsof.globalPosition().eta();
428 
429  double mean = 0;
430  double sigma = 1;
431  //if(!fillMean)
432  {
433  auto ptBin = deltaPhiPropCandMean->FindBin(trackingParticle.pt());
434 
435  mean = deltaPhiPropCandMean->GetBinContent(ptBin);
436  sigma = deltaPhiPropCandStdDev->GetBinContent(ptBin);
437  }
438 
439  result.matchingLikelihood = normal_pdf(result.deltaPhi, mean, sigma); //TODO temporary solution
440 
441  result.muonCand = muonCand;
442  result.procMuon = procMuon;
443 
444  double treshold = 6. * sigma;
445  if (trackingParticle.pt() > 20)
446  treshold = 7. * sigma;
447  if (trackingParticle.pt() > 100)
448  treshold = 20. * sigma;
449 
450  if (abs(result.deltaPhi - mean) < treshold)
452 
453  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << trackingParticle.pdgId()
454  << " pt " << std::setw(8) << trackingParticle.pt() << " eta " << std::setw(8)
455  << trackingParticle.momentum().eta() << " phi " << std::setw(8)
456  << trackingParticle.momentum().phi() << " propagation eta " << std::setw(8)
457  << tsof.globalPosition().eta() << " phi " << tsof.globalPosition().phi()
458  << " muonCand pt " << std::setw(8) << muonCand->hwPt() << " candGloablEta "
459  << std::setw(8) << candGloablEta << " candGlobalPhi " << std::setw(8) << candGlobalPhi
460  << " hwQual " << muonCand->hwQual() << " deltaEta " << std::setw(8) << result.deltaEta
461  << " deltaPhi " << std::setw(8) << result.deltaPhi << " Likelihood " << std::setw(8)
462  << result.matchingLikelihood << " result " << (short)result.result << std::endl;
463  }
464 
465  return result;
466 }
467 
468 std::vector<MatchingResult> CandidateSimMuonMatcher::cleanMatching(std::vector<MatchingResult> matchingResults,
469  std::vector<const l1t::RegionalMuonCand*>& muonCands,
470  AlgoMuons& ghostBustedProcMuons) {
471  //Cleaning the matching
472  std::sort(
473  matchingResults.begin(), matchingResults.end(), [](const MatchingResult& a, const MatchingResult& b) -> bool {
474  return a.matchingLikelihood > b.matchingLikelihood;
475  });
476  for (unsigned int i1 = 0; i1 < matchingResults.size(); i1++) {
478  for (unsigned int i2 = i1 + 1; i2 < matchingResults.size(); i2++) {
479  if ((matchingResults[i1].trackingParticle &&
480  matchingResults[i1].trackingParticle == matchingResults[i2].trackingParticle) ||
481  (matchingResults[i1].simTrack && matchingResults[i1].simTrack == matchingResults[i2].simTrack) ||
482  (matchingResults[i1].muonCand == matchingResults[i2].muonCand)) {
483  //if matchingResults[i1].muonCand == false, then it is also OK here
485  }
486  }
487  }
488  }
489 
490  std::vector<MatchingResult> cleanedMatchingResults;
491  for (auto& matchingResult : matchingResults) {
492  if (matchingResult.result == MatchingResult::ResultType::matched ||
493  matchingResult.muonCand ==
494  nullptr) //adding also the simTracks that are not matched at all, before it is assured that they are not duplicates
495  cleanedMatchingResults.push_back(matchingResult);
496  if (matchingResult.result == MatchingResult::ResultType::matched) {
497  /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed
498  if(fillMean) {
499  double ptGen = matchingResult.genPt;
500  deltaPhiPropCandMean->Fill(ptGen, matchingResult.deltaPhi); //filling overflow is ok here
501  deltaPhiPropCandStdDev->Fill(ptGen, matchingResult.deltaPhi * matchingResult.deltaPhi);
502  }*/
503  }
504  }
505 
506  //adding the muonCand-s that were not matched, i.e. in order to analyze them later
507  unsigned int iCand = 0;
508  for (auto& muonCand : muonCands) {
509  bool isMatched = false;
510  for (auto& matchingResult : cleanedMatchingResults) {
511  if (matchingResult.muonCand == muonCand) {
512  isMatched = true;
513  break;
514  }
515  }
516 
517  if (!isMatched) {
519  result.muonCand = muonCand;
520  result.procMuon = ghostBustedProcMuons.at(iCand);
521  cleanedMatchingResults.push_back(result);
522  }
523  iCand++;
524  }
525 
526  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::cleanMatching:" << __LINE__
527  << " CandidateSimMuonMatcher::match cleanedMatchingResults:" << std::endl;
528  for (auto& result : cleanedMatchingResults) {
529  if (result.trackingParticle || result.simTrack)
530  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::cleanMatching:" << __LINE__ << " simTrack type "
531  << result.pdgId << " pt " << std::setw(8) << result.genPt << " eta " << std::setw(8)
532  << result.genEta << " phi " << std::setw(8) << result.genPhi;
533  else
534  LogTrace("l1tOmtfEventPrint") << "no matched track ";
535 
536  if (result.muonCand) {
537  LogTrace("l1tOmtfEventPrint") << " muonCand pt " << std::setw(8) << result.muonCand->hwPt() << " hwQual "
538  << result.muonCand->hwQual() << " hwEta " << result.muonCand->hwEta()
539  << " deltaEta " << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8)
540  << result.deltaPhi << " Likelihood " << std::setw(8) << result.matchingLikelihood
541  << " result " << (short)result.result;
542  LogTrace("l1tOmtfEventPrint") << " procMuon " << *(result.procMuon) << std::endl;
543  } else
544  LogTrace("l1tOmtfEventPrint") << " no muonCand "
545  << " result " << (short)result.result << std::endl;
546  }
547  LogTrace("l1tOmtfEventPrint") << " " << std::endl;
548 
549  return cleanedMatchingResults;
550 }
551 
552 std::vector<MatchingResult> CandidateSimMuonMatcher::match(std::vector<const l1t::RegionalMuonCand*>& muonCands,
553  AlgoMuons& ghostBustedProcMuons,
556  std::function<bool(const SimTrack&)> const& simTrackFilter) {
557  std::vector<MatchingResult> matchingResults;
558 
559  for (auto& simTrack : *simTracks) {
560  if (!simTrackFilter(simTrack))
561  continue;
562 
563  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match, simTrack type " << std::setw(3) << simTrack.type()
564  << " pt " << std::setw(9) << simTrack.momentum().pt() << " eta " << std::setw(9)
565  << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi()
566  << std::endl;
567 
568  bool matched = false;
569 
571  if (!tsof.isValid()) {
572  LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " propagation failed" << std::endl;
575  continue; //no sense to do matching
576  }
577 
578  /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed
579  double ptGen = simTrack.momentum().pt();
580  if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax())
581  ptGen = deltaPhiVertexProp->GetXaxis()->GetXmax() - 0.01;
582 
583  deltaPhiVertexProp->Fill(ptGen, simTrack.momentum().phi() - tsof.globalPosition().phi());*/
584 
585  unsigned int iCand = 0;
586  for (auto& muonCand : muonCands) {
587  //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive
588  //if(muonCand->hwQual() > 1)
589  {
590  MatchingResult result = match(muonCand, ghostBustedProcMuons.at(iCand), simTrack, tsof);
592  matchingResults.push_back(result);
593  matched = true;
594  }
595  }
596  iCand++;
597  }
598 
599  if (!matched) { //we are adding also if it was not matching to any candidate
601  matchingResults.push_back(result);
602  LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl;
603  }
604  }
605 
606  return cleanMatching(matchingResults, muonCands, ghostBustedProcMuons);
607 }
608 
609 std::vector<MatchingResult> CandidateSimMuonMatcher::match(
610  std::vector<const l1t::RegionalMuonCand*>& muonCands,
611  AlgoMuons& ghostBustedProcMuons,
613  std::function<bool(const TrackingParticle&)> const& simTrackFilter) {
614  std::vector<MatchingResult> matchingResults;
615  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match trackingParticles->size() "
616  << trackingParticles->size() << std::endl;
617 
618  for (auto& trackingParticle : *trackingParticles) {
619  //LogTrace("l1tOmtfEventPrint") <<"CandidateSimMuonMatcher::match:"<<__LINE__<<" trackingParticle type "<<std::setw(3)<<trackingParticle.pdgId()<<" pt "<<std::setw(9)<<trackingParticle.pt()<<" eta "<<std::setw(9)<<trackingParticle.momentum().eta()<<" phi "<<std::setw(9)<<trackingParticle.momentum().phi()<<std::endl;
620 
621  if (simTrackFilter(trackingParticle) == false)
622  continue;
623 
624  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match, trackingParticle type " << std::setw(3)
625  << trackingParticle.pdgId() << " pt " << std::setw(9) << trackingParticle.pt()
626  << " eta " << std::setw(9) << trackingParticle.momentum().eta() << " phi "
627  << std::setw(9) << trackingParticle.momentum().phi() << std::endl;
628 
629  bool matched = false;
630 
631  TrajectoryStateOnSurface tsof = propagate(trackingParticle);
632  if (!tsof.isValid()) {
633  LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match:" << __LINE__ << " propagation failed"
634  << std::endl;
637  continue; //no sense to do matching
638  }
639 
640  /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed
641  double ptGen = trackingParticle.pt();
642  if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax())
643  ptGen = deltaPhiVertexProp->GetXaxis()->GetXmax() - 0.01;
644 
645  deltaPhiVertexProp->Fill(ptGen, trackingParticle.momentum().phi() - tsof.globalPosition().phi());
646 */
647  unsigned int iCand = 0;
648  for (auto& muonCand : muonCands) {
649  //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive then
650  /*if(muonCand->hwQual() <= 1)
651  continue; */
652 
654  if (tsof.isValid()) {
655  result = match(muonCand, ghostBustedProcMuons.at(iCand), trackingParticle, tsof);
656  }
657  iCand++;
658 
660  matchingResults.push_back(result);
661  matched = true;
662  }
663  }
664 
665  if (!matched) { //we are adding result also if it there was no matching to any candidate
666  MatchingResult result(trackingParticle);
667  matchingResults.push_back(result);
668  LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl;
669  }
670  }
671 
672  return cleanMatching(matchingResults, muonCands, ghostBustedProcMuons);
673 }
const int hwPhi() const
Get compressed local phi (returned int * 2*pi/576 = local phi in rad)
MatchingResult match(const l1t::RegionalMuonCand *omtfCand, const AlgoMuonPtr &procMuon, const SimTrack &simTrack, TrajectoryStateOnSurface &tsof)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
int pdgId() const
PDG ID.
EncodedEventId eventId() const
Signal source, crossing number.
Vector momentum() const
spatial momentum vector
int event() const
get the contents of the subdetector field (should be protected?)
double hwGmtPhiToGlobalPhi(int phi)
double vx() const
x coordinate of parent vertex position
bool trackingParticleIsMuonInOmtfEvent0(const TrackingParticle &trackingParticle)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
edm::ESHandle< MagneticField > magField
bool exists(std::string const &parameterName) const
checks if a parameter exists
T eta() const
Definition: PV3DBase.h:73
const int processor() const
Get processor ID on which the candidate was found (0..5 for OMTF/EMTF; 0..11 for BMTF) ...
T const * product() const
Definition: Handle.h:70
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
float normal_pdf(float x, float m, float s)
Cylinder BoundCylinder
Definition: BoundCylinder.h:17
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
void beginRun(edm::EventSetup const &eventSetup) override
TrajectoryStateOnSurface propagate(const SimTrack &simTrack, const edm::SimVertexContainer *simVertices)
Log< level::Error, false > LogError
const int hwPt() const
Get compressed pT (returned int * 0.5 = pT (GeV))
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
CandidateSimMuonMatcher(const edm::ParameterSet &edmCfg, const OMTFConfiguration *omtfConfig, const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > &magneticFieldEsToken, const edm::ESGetToken< Propagator, TrackingComponentsRecord > &propagatorEsToken)
void observeProcesorEmulation(unsigned int iProcessor, l1t::tftype mtfType, const std::shared_ptr< OMTFinput > &, const AlgoMuons &algoCandidates, const AlgoMuons &gbCandidates, const std::vector< l1t::RegionalMuonCand > &candMuons) override
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:19
const std::vector< SimTrack > & g4Tracks() const
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:50
bool simTrackIsMuonInOmtf(const SimTrack &simTrack)
const int hwQual() const
Get quality code.
const int hwEta() const
Get compressed eta (returned int * 0.010875 = eta)
std::vector< MatchingResult > cleanMatching(std::vector< MatchingResult > matchingResults, std::vector< const l1t::RegionalMuonCand *> &muonCands, AlgoMuons &ghostBustedProcMuons)
unsigned size(int bx) const
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:22
bool simTrackIsMuonInOmtfBx0(const SimTrack &simTrack)
double foldPhi(double phi)
const edm::ESGetToken< Propagator, TrackingComponentsRecord > & propagatorEsToken
GlobalPoint globalPosition() const
const edm::ParameterSet & edmCfg
int bunchCrossing() const
get the detector field from this detid
const tftype trackFinderType() const
Get track-finder which found the muon (bmtf, emtf_pos/emtf_neg or omtf_pos/omtf_neg) ...
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
TrajectoryStateOnSurface atStation2(FreeTrajectoryState ftsStart, float eta) const
Log< level::Error, true > LogImportant
bool isMatched(TrackingRecHit const &hit)
const T & at(int bx, unsigned i) const
#define M_PI
FreeTrajectoryState simTrackToFts(const SimTrack &simTrack, const SimVertex &simVertex)
void observeEventBegin(const edm::Event &event) override
static int calcGlobalPhi(int locPhi, tftype t, int proc)
const TrackingVertexRef & parentVertex() const
double vy() const
y coordinate of parent vertex position
std::vector< SimVertex > SimVertexContainer
double b
Definition: hdecay.h:118
edm::ESHandle< Propagator > propagator
Disk BoundDisk
Definition: BoundDisk.h:54
std::vector< AlgoMuonPtr > AlgoMuons
Definition: AlgoMuon.h:102
double a
Definition: hdecay.h:119
float x
Monte Carlo truth information used for tracking validation.
bool trackingParticleIsMuonInOmtfBx0(const TrackingParticle &trackingParticle)
std::shared_ptr< AlgoMuon > AlgoMuonPtr
Definition: AlgoMuon.h:101
std::vector< TrackingParticle > TrackingParticleCollection
double pt() const
Transverse momentum. Note this is taken from the first SimTrack only.
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > & magneticFieldEsToken
std::vector< MatchingResult > matchingResults
std::vector< SimTrack > SimTrackContainer
Definition: event.py:1
void observeEventEnd(const edm::Event &event, std::unique_ptr< l1t::RegionalMuonCandBxCollection > &finalCandidates) override
static std::vector< const l1t::RegionalMuonCand * > ghostBust(const l1t::RegionalMuonCandBxCollection *mtfCands, const AlgoMuons &gbCandidates, AlgoMuons &ghostBustedProcMuons)
double vz() const
z coordinate of parent vertex position