CMS 3D CMS Logo

CosmicMuonSeedGenerator.cc
Go to the documentation of this file.
13 
15 
17 
23 
27 
29 
30 #include <vector>
31 
34 
35 using namespace edm;
36 using namespace std;
37 
38 // Constructor
40  produces<TrajectorySeedCollection>();
41 
42  // enable the DT chamber
43  theEnableDTFlag = pset.getParameter<bool>("EnableDTMeasurement");
44  // enable the CSC chamber
45  theEnableCSCFlag = pset.getParameter<bool>("EnableCSCMeasurement");
46 
47  theDTRecSegmentLabel = pset.getParameter<InputTag>("DTRecSegmentLabel");
48 
49  theCSCRecSegmentLabel = pset.getParameter<InputTag>("CSCRecSegmentLabel");
50 
51  // the maximum number of TrajectorySeed
52  theMaxSeeds = pset.getParameter<int>("MaxSeeds");
53 
54  theMaxDTChi2 = pset.getParameter<double>("MaxDTChi2");
55  theMaxCSCChi2 = pset.getParameter<double>("MaxCSCChi2");
56 
57  theForcePointDownFlag = pset.existsAs<bool>("ForcePointDown") ? pset.getParameter<bool>("ForcePointDown") : true;
58 
59  // pre-determined parameters for seed pt calculation ( pt * dphi )
60  theParameters["topmb41"] = 0.87;
61  theParameters["bottommb41"] = 1.2;
62  theParameters["topmb42"] = 0.67;
63  theParameters["bottommb42"] = 0.98;
64  theParameters["topmb43"] = 0.34;
65  theParameters["bottommb43"] = 0.58;
66  theParameters["topmb31"] = 0.54;
67  theParameters["bottommb31"] = 0.77;
68  theParameters["topmb32"] = 0.35;
69  theParameters["bottommb32"] = 0.55;
70  theParameters["topmb21"] = 0.21;
71  theParameters["bottommb21"] = 0.31;
72 
73  edm::ConsumesCollector iC = consumesCollector();
74  muonMeasurements = new MuonDetLayerMeasurements(theDTRecSegmentLabel,
75  theCSCRecSegmentLabel,
76 
77  InputTag(),
78  InputTag(),
79  InputTag(),
80  iC,
81  theEnableDTFlag,
82  theEnableCSCFlag,
83  false,
84  false,
85  false);
86  muonLayersToken = esConsumes<MuonDetLayerGeometry, MuonRecoGeometryRecord>();
87  magFieldToken = esConsumes<MagneticField, IdealMagneticFieldRecord>();
88 }
89 
90 // Destructor
92  if (muonMeasurements)
93  delete muonMeasurements;
94 }
95 
96 // reconstruct muon's seeds
98  theField = eSetup.getHandle(magFieldToken);
99 
100  auto output = std::make_unique<TrajectorySeedCollection>();
101 
103 
104  std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
105 
106  // Muon Geometry - DT, CSC and RPC
107  theMuonLayers = eSetup.getHandle(muonLayersToken);
108 
109  // get the DT layers
110  vector<const DetLayer*> dtLayers = theMuonLayers->allDTLayers();
111 
112  // get the CSC layers
113  vector<const DetLayer*> cscForwardLayers = theMuonLayers->forwardCSCLayers();
114  vector<const DetLayer*> cscBackwardLayers = theMuonLayers->backwardCSCLayers();
115 
116  muonMeasurements->setEvent(event);
117 
118  MuonRecHitContainer allHits;
119 
120  vector<MuonRecHitContainer> RHMBs;
121  vector<MuonRecHitContainer> RHMEFs;
122  vector<MuonRecHitContainer> RHMEBs;
123 
124  stable_sort(allHits.begin(), allHits.end(), DecreasingGlobalY());
125 
126  for (vector<const DetLayer*>::reverse_iterator icsclayer = cscForwardLayers.rbegin();
127  icsclayer != cscForwardLayers.rend() - 1;
128  ++icsclayer) {
129  MuonRecHitContainer RHMF = muonMeasurements->recHits(*icsclayer);
130  allHits.insert(allHits.end(), RHMF.begin(), RHMF.end());
131  }
132 
133  for (vector<const DetLayer*>::reverse_iterator icsclayer = cscBackwardLayers.rbegin();
134  icsclayer != cscBackwardLayers.rend() - 1;
135  ++icsclayer) {
136  MuonRecHitContainer RHMF = muonMeasurements->recHits(*icsclayer);
137  allHits.insert(allHits.end(), RHMF.begin(), RHMF.end());
138  }
139 
140  for (vector<const DetLayer*>::reverse_iterator idtlayer = dtLayers.rbegin(); idtlayer != dtLayers.rend();
141  ++idtlayer) {
142  MuonRecHitContainer RHMB = muonMeasurements->recHits(*idtlayer);
143  RHMBs.push_back(RHMB);
144 
145  if (idtlayer != dtLayers.rbegin())
146  allHits.insert(allHits.end(), RHMB.begin(), RHMB.end());
147  }
148 
149  // stable_sort(allHits.begin(),allHits.end(),DecreasingGlobalY());
150 
151  LogTrace(category) << "all RecHits: " << allHits.size();
152 
153  // CosmicMuonSeedGenerator::MuonRecHitPairVector mb41 = makeSegPairs(RHMBs[0], RHMBs[3], "mb41");
154  // createSeeds(seeds, mb41, eSetup);
155 
156  // CosmicMuonSeedGenerator::MuonRecHitPairVector mb43 = makeSegPairs(RHMBs[0],RHMBs[1], "mb43");
157  // createSeeds(seeds, mb43, eSetup);
158 
159  CosmicMuonSeedGenerator::MuonRecHitPairVector mb42 = makeSegPairs(RHMBs[0], RHMBs[2], "mb42");
160  createSeeds(seeds, mb42, eSetup);
161 
162  // CosmicMuonSeedGenerator::MuonRecHitPairVector mb32 = makeSegPairs(RHMBs[1], RHMBs[2], "mb32");
163  // createSeeds(seeds, mb32, eSetup);
164 
165  CosmicMuonSeedGenerator::MuonRecHitPairVector mb31 = makeSegPairs(RHMBs[1], RHMBs[3], "mb31");
166  createSeeds(seeds, mb31, eSetup);
167 
168  // CosmicMuonSeedGenerator::MuonRecHitPairVector mb21 = makeSegPairs(RHMBs[2], RHMBs[3], "mb21");
169  // createSeeds(seeds, mb21, eSetup);
170 
171  if (!allHits.empty()) {
172  MuonRecHitContainer goodhits = selectSegments(allHits);
173  LogTrace(category) << "good RecHits: " << goodhits.size();
174 
175  if (goodhits.empty()) {
176  LogTrace(category) << "No qualified Segments in Event! ";
177  LogTrace(category) << "Use 2D RecHit";
178 
179  createSeeds(seeds, allHits, eSetup);
180 
181  } else {
182  createSeeds(seeds, goodhits, eSetup);
183  }
184  }
185 
186  LogTrace(category) << "Seeds built: " << seeds.size();
187 
188  for (std::vector<TrajectorySeed>::iterator seed = seeds.begin(); seed != seeds.end(); ++seed) {
189  output->push_back(*seed);
190  }
191 
192  event.put(std::move(output));
193  seeds.clear();
194 }
195 
197  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
198 
199  // only use 4D segments
200  if (!hit->isValid())
201  return false;
202 
203  if (hit->dimension() < 4) {
204  LogTrace(category) << "dim < 4";
205  return false;
206  }
207 
208  if (hit->isDT() && (hit->chi2() > theMaxDTChi2)) {
209  LogTrace(category) << "DT chi2 too large";
210  return false;
211  } else if (hit->isCSC() && (hit->chi2() > theMaxCSCChi2)) {
212  LogTrace(category) << "CSC chi2 too large";
213  return false;
214  }
215  return true;
216 }
217 
220  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
221 
222  //Only select good quality Segments
223  for (MuonRecHitContainer::const_iterator hit = hits.begin(); hit != hits.end(); hit++) {
224  if (checkQuality(*hit))
225  result.push_back(*hit);
226  }
227 
228  if (result.size() < 2)
229  return result;
230 
231  MuonRecHitContainer result2;
232 
233  //avoid selecting Segments with similar direction
234  for (MuonRecHitContainer::iterator hit = result.begin(); hit != result.end(); hit++) {
235  if (*hit == nullptr)
236  continue;
237  if (!(*hit)->isValid())
238  continue;
239  bool good = true;
240  //UNUSED: GlobalVector dir1 = (*hit)->globalDirection();
241  //UNUSED: GlobalPoint pos1 = (*hit)->globalPosition();
242  for (MuonRecHitContainer::iterator hit2 = hit + 1; hit2 != result.end(); hit2++) {
243  if (*hit2 == nullptr)
244  continue;
245  if (!(*hit2)->isValid())
246  continue;
247 
248  //compare direction and position
249  //UNUSED: GlobalVector dir2 = (*hit2)->globalDirection();
250  //UNUSED: GlobalPoint pos2 = (*hit2)->globalPosition();
251  if (!areCorrelated((*hit), (*hit2)))
252  continue;
253 
254  if (!leftIsBetter((*hit), (*hit2))) {
255  good = false;
256  } else
257  (*hit2) = nullptr;
258  }
259 
260  if (good)
261  result2.push_back(*hit);
262  }
263 
264  result.clear();
265 
266  return result2;
267 }
268 
270  const MuonRecHitContainer& hits,
271  const edm::EventSetup& eSetup) const {
272  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
273 
274  if (hits.empty() || results.size() >= theMaxSeeds)
275  return;
276  for (MuonRecHitContainer::const_iterator ihit = hits.begin(); ihit != hits.end(); ihit++) {
277  const std::vector<TrajectorySeed>& sds = createSeed((*ihit), eSetup);
278  LogTrace(category) << "created seeds from rechit " << sds.size();
279  results.insert(results.end(), sds.begin(), sds.end());
280  if (results.size() >= theMaxSeeds)
281  break;
282  }
283  return;
284 }
285 
288  const edm::EventSetup& eSetup) const {
289  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
290 
291  if (hitpairs.empty() || results.size() >= theMaxSeeds)
292  return;
293  for (CosmicMuonSeedGenerator::MuonRecHitPairVector::const_iterator ihitpair = hitpairs.begin();
294  ihitpair != hitpairs.end();
295  ihitpair++) {
296  const std::vector<TrajectorySeed>& sds = createSeed((*ihitpair), eSetup);
297  LogTrace(category) << "created seeds from rechit " << sds.size();
298  results.insert(results.end(), sds.begin(), sds.end());
299  if (results.size() >= theMaxSeeds)
300  break;
301  }
302  return;
303 }
304 
305 std::vector<TrajectorySeed> CosmicMuonSeedGenerator::createSeed(const MuonRecHitPointer& hit,
306  const edm::EventSetup& eSetup) const {
307  std::vector<TrajectorySeed> result;
308 
309  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
310 
311  MuonPatternRecoDumper dumper;
312 
313  // set the pt by hand
314  double pt = 10.0;
315 
316  // AlgebraicVector4 t;
317  AlgebraicSymMatrix mat(5, 0);
318 
319  // Fill the LocalTrajectoryParameters
320  LocalPoint segPos = hit->localPosition();
321 
322  GlobalVector polar(GlobalVector::Spherical(hit->globalDirection().theta(), hit->globalDirection().phi(), 1.));
323  // Force all track downward for cosmic, not beam-halo
324  if (theForcePointDownFlag) {
325  if (hit->geographicalId().subdetId() == MuonSubdetId::DT && fabs(hit->globalDirection().eta()) < 4.0 &&
326  hit->globalDirection().phi() > 0)
327  polar = -polar;
328 
329  if (hit->geographicalId().subdetId() == MuonSubdetId::CSC && fabs(hit->globalDirection().eta()) > 2.3)
330  polar = -polar;
331  }
332 
333  polar *= fabs(pt) / polar.perp();
334 
335  LocalVector segDir = hit->det()->toLocal(polar);
336 
337  int charge = 1;
338  LocalTrajectoryParameters param(segPos, segDir, charge);
339 
340  charge = -1;
341  LocalTrajectoryParameters param2(segPos, segDir, charge);
342 
343  mat = hit->parametersError().similarityT(hit->projectionMatrix());
344 
345  float p_err = 0.2;
346  mat[0][0] = p_err;
347 
348  LocalTrajectoryError error(asSMatrix<5>(mat));
349 
350  // Create the TrajectoryStateOnSurface
351  TrajectoryStateOnSurface tsos(param, error, hit->det()->surface(), &*theField);
352  TrajectoryStateOnSurface tsos2(param2, error, hit->det()->surface(), &*theField);
353 
354  LogTrace(category) << "Trajectory State on Surface of Seed";
355  LogTrace(category) << "mom: " << tsos.globalMomentum() << " phi: " << tsos.globalMomentum().phi();
356  LogTrace(category) << "pos: " << tsos.globalPosition();
357  LogTrace(category) << "The RecSegment relies on: ";
358  LogTrace(category) << dumper.dumpMuonId(hit->geographicalId());
359 
361  container.push_back(hit->hit()->clone());
362 
363  result.push_back(tsosToSeed(tsos, hit->geographicalId().rawId(), container));
364  result.push_back(tsosToSeed(tsos2, hit->geographicalId().rawId(), container));
365 
366  return result;
367 }
368 
370  bool result = false;
371 
372  GlobalVector dir1 = lhs->globalDirection();
373  GlobalPoint pos1 = lhs->globalPosition();
374  GlobalVector dir2 = rhs->globalDirection();
375  GlobalPoint pos2 = rhs->globalPosition();
376 
377  GlobalVector dis = pos2 - pos1;
378 
379  if ((deltaR<double>(dir1.eta(), dir1.phi(), dir2.eta(), dir2.phi()) < 0.1 ||
380  deltaR<double>(dir1.eta(), dir1.phi(), -dir2.eta(), -dir2.phi()) < 0.1) &&
381  dis.mag() < 5.0)
382  result = true;
383 
384  if ((deltaR<double>(dir1.eta(), dir1.phi(), dir2.eta(), dir2.phi()) < 0.1 ||
385  deltaR<double>(dir1.eta(), dir1.phi(), -dir2.eta(), -dir2.phi()) < 0.1) &&
386  (deltaR<double>(dir1.eta(), dir1.phi(), dis.eta(), dis.phi()) < 0.1 ||
387  deltaR<double>(dir2.eta(), dir2.phi(), dis.eta(), dis.phi()) < 0.1))
388  result = true;
389 
390  if (fabs(dir1.eta()) > 4.0 || fabs(dir2.eta()) > 4.0) {
391  if ((fabs(dir1.theta() - dir2.theta()) < 0.07 || fabs(dir1.theta() + dir2.theta()) > 3.07) &&
392  (fabs(dir1.theta() - dis.theta()) < 0.07 || fabs(dir1.theta() - dis.theta()) < 0.07 ||
393  fabs(dir1.theta() + dis.theta()) > 3.07 || fabs(dir1.theta() + dis.theta()) > 3.07))
394 
395  result = true;
396  }
397 
398  return result;
399 }
400 
403  if ((lhs->degreesOfFreedom() > rhs->degreesOfFreedom()) ||
404  ((lhs->degreesOfFreedom() == rhs->degreesOfFreedom()) && (lhs)->chi2() < (rhs)->chi2()))
405  return true;
406  else
407  return false;
408 }
409 
413  std::string tag) const {
415  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
416 
417  if (hits1.empty() || hits2.empty())
418  return result;
419 
420  for (MuonRecHitContainer::const_iterator ihit1 = hits1.begin(); ihit1 != hits1.end(); ihit1++) {
421  if (!checkQuality(*ihit1))
422  continue;
423 
424  for (MuonRecHitContainer::const_iterator ihit2 = hits2.begin(); ihit2 != hits2.end(); ihit2++) {
425  if (!checkQuality(*ihit2))
426  continue;
427 
428  float dphi = deltaPhi((*ihit1)->globalPosition().barePhi(), (*ihit2)->globalPosition().barePhi());
429  if (dphi < 0.5) {
430  if ((*ihit1)->globalPosition().y() > 0.0 && ((*ihit1)->globalPosition().y() > (*ihit2)->globalPosition().y())) {
431  std::string tag2 = "top" + tag;
432 
433  result.push_back(MuonRecHitPair(*ihit1, *ihit2, tag2));
434  } else if ((*ihit1)->globalPosition().y() < 0.0 &&
435  ((*ihit1)->globalPosition().y() < (*ihit2)->globalPosition().y())) {
436  std::string tag2 = "bottom" + tag;
437  result.push_back(MuonRecHitPair(*ihit2, *ihit1, tag2));
438  }
439  }
440  }
441  }
442 
443  return result;
444 }
445 
447  const edm::EventSetup& eSetup) const {
448  std::vector<TrajectorySeed> result;
449 
450  const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
451 
452  MuonPatternRecoDumper dumper;
453 
454  float dphi = deltaPhi((hitpair.first)->globalDirection().barePhi(), (hitpair.second)->globalDirection().barePhi());
455 
456  LogTrace(category) << "hitpair.type " << hitpair.type;
457 
458  map<string, float>::const_iterator iterPar = theParameters.find(hitpair.type);
459  if (iterPar == theParameters.end()) {
460  return result;
461  }
462 
463  // set the pt and charge by dphi
464  int charge = (dphi > 0) ? -1 : 1;
465 
466  double pt = 999.0;
467  float paraC = (iterPar->second);
468 
469  if (fabs(dphi) > 1e-5) {
470  pt = paraC / fabs(dphi);
471  }
472 
473  if (pt < 10.0) {
474  return result;
475  } //still use the old strategy for low pt
476 
477  AlgebraicVector t(4);
478  AlgebraicSymMatrix mat(5, 0);
479 
481  if (hit->dimension() < (hitpair.second)->dimension())
482  hit = hitpair.second;
483 
484  // Fill the LocalTrajectoryParameters
485  LocalPoint segPos = hit->localPosition();
486 
487  GlobalVector polar(GlobalVector::Spherical(hit->globalDirection().theta(), hit->globalDirection().phi(), 1.));
488  // Force all track downward for cosmic, not beam-halo
489  if (theForcePointDownFlag) {
490  if (hit->geographicalId().subdetId() == MuonSubdetId::DT && fabs(hit->globalDirection().eta()) < 4.0 &&
491  hit->globalDirection().phi() > 0)
492  polar = -polar;
493 
494  if (hit->geographicalId().subdetId() == MuonSubdetId::CSC && fabs(hit->globalDirection().eta()) > 2.3)
495  polar = -polar;
496  }
497 
498  polar *= fabs(pt) / polar.perp();
499 
500  LocalVector segDir = hit->det()->toLocal(polar);
501 
502  LocalTrajectoryParameters param(segPos, segDir, charge);
503 
504  mat = hit->parametersError().similarityT(hit->projectionMatrix());
505 
506  float p_err = 0.004 / paraC;
507  if (pt < 10.01)
508  p_err = 0.1;
509  mat[0][0] = p_err;
510 
511  LocalTrajectoryError error(asSMatrix<5>(mat));
512 
513  // Create the TrajectoryStateOnSurface
514  TrajectoryStateOnSurface tsos(param, error, hit->det()->surface(), &*theField);
515 
516  LogTrace(category) << "Trajectory State on Surface of Seed";
517  LogTrace(category) << "mom: " << tsos.globalMomentum() << " phi: " << tsos.globalMomentum().phi();
518  LogTrace(category) << "pos: " << tsos.globalPosition();
519  LogTrace(category) << "The RecSegment relies on: ";
520  LogTrace(category) << dumper.dumpMuonId(hit->geographicalId());
521 
523  container.push_back(hitpair.first->hit()->clone());
524  container.push_back(hitpair.second->hit()->clone());
525 
526  result.push_back(tsosToSeed(tsos, hit->geographicalId().rawId(), container));
527 
528  return result;
529 }
530 
533  return tsosToSeed(tsos, id, container);
534 }
535 
537  uint32_t id,
538  edm::OwnVector<TrackingRecHit>& container) const {
540  TrajectorySeed seed(seedTSOS, container, alongMomentum);
541  return seed;
542 }
std::string dumpMuonId(const DetId &id) const
T perp() const
Definition: PV3DBase.h:69
MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer
MuonTransientTrackingRecHit::MuonRecHitPointer MuonRecHitPointer
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
T eta() const
Definition: PV3DBase.h:73
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
MuonTransientTrackingRecHit::MuonRecHitPointer first
#define LogTrace(id)
bool checkQuality(const MuonTransientTrackingRecHit::MuonRecHitPointer &) const
determine if a MuonTransientTrackingRecHit is qualified to build seed
void push_back(D *&d)
Definition: OwnVector.h:326
std::vector< MuonRecHitPair > makeSegPairs(const MuonTransientTrackingRecHit::MuonRecHitContainer &, const MuonTransientTrackingRecHit::MuonRecHitContainer &, std::string) const
TrajectorySeed tsosToSeed(const TrajectoryStateOnSurface &, uint32_t) const
std::vector< TrajectorySeed > TrajectorySeedCollection
std::shared_ptr< MuonTransientTrackingRecHit > MuonRecHitPointer
T mag() const
Definition: PV3DBase.h:64
MuonTransientTrackingRecHit::MuonRecHitContainer selectSegments(const MuonTransientTrackingRecHit::MuonRecHitContainer &) const
select seed candidates from Segments in Event
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:151
std::vector< TrajectorySeed > createSeed(const MuonTransientTrackingRecHit::MuonRecHitPointer &, const edm::EventSetup &) const
create TrajectorySeed from MuonTransientTrackingRecHit
std::vector< MuonRecHitPair > MuonRecHitPairVector
CLHEP::HepVector AlgebraicVector
auto const good
min quality of good
MuonTransientTrackingRecHit::MuonRecHitPointer MuonRecHitPointer
MuonTransientTrackingRecHit::MuonRecHitPointer second
~CosmicMuonSeedGenerator() override
Destructor.
HLT enums.
bool leftIsBetter(const MuonTransientTrackingRecHit::MuonRecHitPointer &, const MuonTransientTrackingRecHit::MuonRecHitPointer &) const
compare quality of two rechits
CLHEP::HepSymMatrix AlgebraicSymMatrix
MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer
void produce(edm::Event &, const edm::EventSetup &) override
reconstruct muon&#39;s seeds
static constexpr int DT
Definition: MuonSubdetId.h:11
bool areCorrelated(const MuonTransientTrackingRecHit::MuonRecHitPointer &, const MuonTransientTrackingRecHit::MuonRecHitPointer &) const
check if two rechits are correlated
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
static constexpr int CSC
Definition: MuonSubdetId.h:12
std::vector< MuonRecHitPointer > MuonRecHitContainer
def move(src, dest)
Definition: eostools.py:511
void createSeeds(TrajectorySeedCollection &results, const MuonTransientTrackingRecHit::MuonRecHitContainer &hits, const edm::EventSetup &eSetup) const
generate TrajectorySeeds and put them into results
CosmicMuonSeedGenerator(const edm::ParameterSet &)
Constructor.
Definition: event.py:1
Geom::Theta< T > theta() const
Definition: PV3DBase.h:72