CMS 3D CMS Logo

TrackDetectorAssociator.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: TrackAssociator
4 // Class: TrackDetectorAssociator
5 //
6 /*
7 
8  Description: <one line class summary>
9 
10  Implementation:
11  <Notes on implementation>
12 */
13 //
14 // Original Author: Dmytro Kovalskyi
15 // Created: Fri Apr 21 10:59:41 PDT 2006
16 //
17 //
18 
23 
27 
45 
46 // calorimeter and muon infos
55 
57 #include <stack>
58 #include <set>
59 
61 #include "Math/VectorUtil.h"
62 #include <algorithm>
63 
70 
71 using namespace reco;
72 
74  ivProp_ = nullptr;
75  useDefaultPropagator_ = false;
76 }
77 
79 
81  ivProp_ = ptr;
82  cachedTrajectory_.setPropagator(ivProp_);
83 }
84 
85 void TrackDetectorAssociator::useDefaultPropagator() { useDefaultPropagator_ = true; }
86 
88  // access the calorimeter geometry
89  theCaloGeometry_ = &iSetup.getData(parameters.theCaloGeometryToken);
90 
91  // get the tracking Geometry
92  theTrackingGeometry_ = &iSetup.getData(parameters.theTrackingGeometryToken);
93 
94  if (useDefaultPropagator_ && (!defProp_ || theMagneticFieldWatcher_.check(iSetup))) {
95  // setup propagator
96  const MagneticField* bField = &iSetup.getData(parameters.bFieldToken);
97 
98  auto prop = std::make_unique<SteppingHelixPropagator>(bField, anyDirection);
99  prop->setMaterialMode(false);
100  prop->applyRadX0Correction(true);
101  // prop->setDebug(true); // tmp
102  defProp_ = std::move(prop);
103  setPropagator(defProp_.get());
104  }
105 
106  ecalDetIdAssociator_ = &iSetup.getData(parameters.ecalDetIdAssociatorToken);
107  hcalDetIdAssociator_ = &iSetup.getData(parameters.hcalDetIdAssociatorToken);
108  hoDetIdAssociator_ = &iSetup.getData(parameters.hoDetIdAssociatorToken);
109  caloDetIdAssociator_ = &iSetup.getData(parameters.caloDetIdAssociatorToken);
110  muonDetIdAssociator_ = &iSetup.getData(parameters.muonDetIdAssociatorToken);
111  preshowerDetIdAssociator_ = &iSetup.getData(parameters.preshowerDetIdAssociatorToken);
112 }
113 
115  const edm::EventSetup& iSetup,
116  const FreeTrajectoryState& fts,
118  return associate(iEvent, iSetup, parameters, &fts);
119 }
120 
122  const edm::EventSetup& iSetup,
124  const FreeTrajectoryState* innerState,
125  const FreeTrajectoryState* outerState) {
127  if (!parameters.useEcal && !parameters.useCalo && !parameters.useHcal && !parameters.useHO && !parameters.useMuon &&
128  !parameters.usePreshower)
129  throw cms::Exception("ConfigurationError")
130  << "Configuration error! No subdetector was selected for the track association.";
131 
132  SteppingHelixStateInfo trackOrigin(*innerState);
133  info.stateAtIP = *innerState;
134  cachedTrajectory_.setStateAtIP(trackOrigin);
135 
136  init(iSetup, parameters);
137  // get track trajectory
138  // ECAL points (EB+EE)
139  // If the phi angle between a track entrance and exit points is more
140  // than 2 crystals, it is possible that the track will cross 3 crystals
141  // and therefore one has to check at least 3 points along the track
142  // trajectory inside ECAL. In order to have a chance to cross 4 crystalls
143  // in the barrel, a track should have P_t as low as 3 GeV or smaller
144  // If it's necessary, number of points along trajectory can be increased
145 
146  info.setCaloGeometry(theCaloGeometry_);
147 
148  cachedTrajectory_.reset_trajectory();
149  // estimate propagation outer boundaries based on
150  // requested sub-detector information. For now limit
151  // propagation region only if muon matching is not
152  // requested.
153  double HOmaxR = hoDetIdAssociator_->volume().maxR();
154  double HOmaxZ = hoDetIdAssociator_->volume().maxZ();
155  double minR = ecalDetIdAssociator_->volume().minR();
156  double minZ = preshowerDetIdAssociator_->volume().minZ();
157  cachedTrajectory_.setMaxHORadius(HOmaxR);
158  cachedTrajectory_.setMaxHOLength(HOmaxZ * 2.);
159  cachedTrajectory_.setMinDetectorRadius(minR);
160  cachedTrajectory_.setMinDetectorLength(minZ * 2.);
161 
162  if (parameters.useMuon) {
163  double maxR = muonDetIdAssociator_->volume().maxR();
164  double maxZ = muonDetIdAssociator_->volume().maxZ();
165  cachedTrajectory_.setMaxDetectorRadius(maxR);
166  cachedTrajectory_.setMaxDetectorLength(maxZ * 2.);
167  } else {
168  cachedTrajectory_.setMaxDetectorRadius(HOmaxR);
169  cachedTrajectory_.setMaxDetectorLength(HOmaxZ * 2.);
170  }
171 
172  // If track extras exist and outerState is before HO maximum, then use outerState
173  if (outerState) {
174  if (outerState->position().perp() < HOmaxR && std::abs(outerState->position().z()) < HOmaxZ) {
175  LogTrace("TrackAssociator") << "Using outerState as trackOrigin at Rho=" << outerState->position().perp()
176  << " Z=" << outerState->position().z() << "\n";
177  trackOrigin = SteppingHelixStateInfo(*outerState);
178  } else if (innerState) {
179  LogTrace("TrackAssociator") << "Using innerState as trackOrigin at Rho=" << innerState->position().perp()
180  << " Z=" << innerState->position().z() << "\n";
181  trackOrigin = SteppingHelixStateInfo(*innerState);
182  }
183  }
184 
185  if (trackOrigin.momentum().mag() == 0)
186  return info;
187  if (edm::isNotFinite(trackOrigin.momentum().x()) or edm::isNotFinite(trackOrigin.momentum().y()) or
188  edm::isNotFinite(trackOrigin.momentum().z()))
189  return info;
190  if (!cachedTrajectory_.propagateAll(trackOrigin))
191  return info;
192 
193  // get trajectory in calorimeters
194  cachedTrajectory_.findEcalTrajectory(ecalDetIdAssociator_->volume());
195  cachedTrajectory_.findHcalTrajectory(hcalDetIdAssociator_->volume());
196  cachedTrajectory_.findHOTrajectory(hoDetIdAssociator_->volume());
197  cachedTrajectory_.findPreshowerTrajectory(preshowerDetIdAssociator_->volume());
198 
199  info.trkGlobPosAtEcal = getPoint(cachedTrajectory_.getStateAtEcal().position());
200  info.trkGlobPosAtHcal = getPoint(cachedTrajectory_.getStateAtHcal().position());
201  info.trkGlobPosAtHO = getPoint(cachedTrajectory_.getStateAtHO().position());
202 
203  info.trkMomAtEcal = cachedTrajectory_.getStateAtEcal().momentum();
204  info.trkMomAtHcal = cachedTrajectory_.getStateAtHcal().momentum();
205  info.trkMomAtHO = cachedTrajectory_.getStateAtHO().momentum();
206 
207  if (parameters.useEcal)
208  fillEcal(iEvent, info, parameters);
209  if (parameters.useCalo)
210  fillCaloTowers(iEvent, info, parameters);
211  if (parameters.useHcal)
212  fillHcal(iEvent, info, parameters);
213  if (parameters.useHO)
214  fillHO(iEvent, info, parameters);
215  if (parameters.usePreshower)
216  fillPreshower(iEvent, info, parameters);
217  if (parameters.useMuon)
218  fillMuon(iEvent, info, parameters);
219  if (parameters.truthMatch)
220  fillCaloTruth(iEvent, info, parameters);
221 
222  return info;
223 }
224 
228  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getEcalTrajectory();
229 
230  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
231  itr != trajectoryStates.end();
232  itr++)
233  LogTrace("TrackAssociator") << "ECAL trajectory point (rho, z, phi): " << itr->position().perp() << ", "
234  << itr->position().z() << ", " << itr->position().phi();
235 
236  std::vector<GlobalPoint> coreTrajectory;
237  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
238  itr != trajectoryStates.end();
239  itr++)
240  coreTrajectory.push_back(itr->position());
241 
242  if (coreTrajectory.empty()) {
243  LogTrace("TrackAssociator") << "ECAL track trajectory is empty; moving on\n";
244  info.isGoodEcal = false;
245  return;
246  }
247  info.isGoodEcal = true;
248 
249  // Find ECAL crystals
251  iEvent.getByToken(parameters.EBRecHitsToken, EBRecHits);
252  if (!EBRecHits.isValid())
253  throw cms::Exception("FatalError") << "Unable to find EBRecHitCollection in the event!\n";
254 
256  iEvent.getByToken(parameters.EERecHitsToken, EERecHits);
257  if (!EERecHits.isValid())
258  throw cms::Exception("FatalError") << "Unable to find EERecHitCollection in event!\n";
259 
260  std::set<DetId> ecalIdsInRegion;
261  if (parameters.accountForTrajectoryChangeCalo) {
262  // get trajectory change with respect to initial state
263  DetIdAssociator::MapRange mapRange =
264  getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToEcal), parameters.dREcalPreselection);
265  ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
266  } else
267  ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dREcalPreselection);
268  LogTrace("TrackAssociator") << "ECAL hits in the region: " << ecalIdsInRegion.size();
269  if (parameters.dREcalPreselection > parameters.dREcal)
270  ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsInACone(ecalIdsInRegion, coreTrajectory, parameters.dREcal);
271  LogTrace("TrackAssociator") << "ECAL hits in the cone: " << ecalIdsInRegion.size();
272  info.crossedEcalIds = ecalDetIdAssociator_->getCrossedDetIds(ecalIdsInRegion, coreTrajectory);
273  const std::vector<DetId>& crossedEcalIds = info.crossedEcalIds;
274  LogTrace("TrackAssociator") << "ECAL crossed hits " << crossedEcalIds.size();
275 
276  // add EcalRecHits
277  for (std::vector<DetId>::const_iterator itr = crossedEcalIds.begin(); itr != crossedEcalIds.end(); itr++) {
278  std::vector<EcalRecHit>::const_iterator ebHit = (*EBRecHits).find(*itr);
279  std::vector<EcalRecHit>::const_iterator eeHit = (*EERecHits).find(*itr);
280  if (ebHit != (*EBRecHits).end())
281  info.crossedEcalRecHits.push_back(&*ebHit);
282  else if (eeHit != (*EERecHits).end())
283  info.crossedEcalRecHits.push_back(&*eeHit);
284  else
285  LogTrace("TrackAssociator") << "Crossed EcalRecHit is not found for DetId: " << itr->rawId();
286  }
287  for (std::set<DetId>::const_iterator itr = ecalIdsInRegion.begin(); itr != ecalIdsInRegion.end(); itr++) {
288  std::vector<EcalRecHit>::const_iterator ebHit = (*EBRecHits).find(*itr);
289  std::vector<EcalRecHit>::const_iterator eeHit = (*EERecHits).find(*itr);
290  if (ebHit != (*EBRecHits).end())
291  info.ecalRecHits.push_back(&*ebHit);
292  else if (eeHit != (*EERecHits).end())
293  info.ecalRecHits.push_back(&*eeHit);
294  else
295  LogTrace("TrackAssociator") << "EcalRecHit from the cone is not found for DetId: " << itr->rawId();
296  }
297 }
298 
302  // use ECAL and HCAL trajectories to match a tower. (HO isn't used for matching).
303  std::vector<GlobalPoint> trajectory;
304  const std::vector<SteppingHelixStateInfo>& ecalTrajectoryStates = cachedTrajectory_.getEcalTrajectory();
305  const std::vector<SteppingHelixStateInfo>& hcalTrajectoryStates = cachedTrajectory_.getHcalTrajectory();
306  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = ecalTrajectoryStates.begin();
307  itr != ecalTrajectoryStates.end();
308  itr++)
309  trajectory.push_back(itr->position());
310  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = hcalTrajectoryStates.begin();
311  itr != hcalTrajectoryStates.end();
312  itr++)
313  trajectory.push_back(itr->position());
314 
315  if (trajectory.empty()) {
316  LogTrace("TrackAssociator") << "HCAL trajectory is empty; moving on\n";
317  info.isGoodCalo = false;
318  return;
319  }
320  info.isGoodCalo = true;
321 
322  // find crossed CaloTowers
324  iEvent.getByToken(parameters.caloTowersToken, caloTowers);
325  if (!caloTowers.isValid())
326  throw cms::Exception("FatalError") << "Unable to find CaloTowers in event!\n";
327 
328  std::set<DetId> caloTowerIdsInRegion;
329  if (parameters.accountForTrajectoryChangeCalo) {
330  // get trajectory change with respect to initial state
331  DetIdAssociator::MapRange mapRange =
332  getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHcal), parameters.dRHcalPreselection);
333  caloTowerIdsInRegion = caloDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0], mapRange);
334  } else
335  caloTowerIdsInRegion = caloDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0], parameters.dRHcalPreselection);
336 
337  LogTrace("TrackAssociator") << "Towers in the region: " << caloTowerIdsInRegion.size();
338 
339  auto caloTowerIdsInAConeBegin = caloTowerIdsInRegion.begin();
340  auto caloTowerIdsInAConeEnd = caloTowerIdsInRegion.end();
341  std::set<DetId> caloTowerIdsInAConeTmp;
342  if (!caloDetIdAssociator_->selectAllInACone(parameters.dRHcal)) {
343  caloTowerIdsInAConeTmp =
344  caloDetIdAssociator_->getDetIdsInACone(caloTowerIdsInRegion, trajectory, parameters.dRHcal);
345  caloTowerIdsInAConeBegin = caloTowerIdsInAConeTmp.begin();
346  caloTowerIdsInAConeEnd = caloTowerIdsInAConeTmp.end();
347  }
348  LogTrace("TrackAssociator") << "Towers in the cone: "
349  << std::distance(caloTowerIdsInAConeBegin, caloTowerIdsInAConeEnd);
350 
351  info.crossedTowerIds = caloDetIdAssociator_->getCrossedDetIds(caloTowerIdsInRegion, trajectory);
352  const std::vector<DetId>& crossedCaloTowerIds = info.crossedTowerIds;
353  LogTrace("TrackAssociator") << "Towers crossed: " << crossedCaloTowerIds.size();
354 
355  // add CaloTowers
356  for (std::vector<DetId>::const_iterator itr = crossedCaloTowerIds.begin(); itr != crossedCaloTowerIds.end(); itr++) {
357  CaloTowerCollection::const_iterator tower = (*caloTowers).find(*itr);
358  if (tower != (*caloTowers).end())
359  info.crossedTowers.push_back(&*tower);
360  else
361  LogTrace("TrackAssociator") << "Crossed CaloTower is not found for DetId: " << (*itr).rawId();
362  }
363 
364  for (std::set<DetId>::const_iterator itr = caloTowerIdsInAConeBegin; itr != caloTowerIdsInAConeEnd; itr++) {
365  CaloTowerCollection::const_iterator tower = (*caloTowers).find(*itr);
366  if (tower != (*caloTowers).end())
367  info.towers.push_back(&*tower);
368  else
369  LogTrace("TrackAssociator") << "CaloTower from the cone is not found for DetId: " << (*itr).rawId();
370  }
371 }
372 
376  std::vector<GlobalPoint> trajectory;
377  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getPreshowerTrajectory();
378  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
379  itr != trajectoryStates.end();
380  itr++)
381  trajectory.push_back(itr->position());
382 
383  if (trajectory.empty()) {
384  LogTrace("TrackAssociator") << "Preshower trajectory is empty; moving on\n";
385  return;
386  }
387 
388  std::set<DetId> idsInRegion =
389  preshowerDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0], parameters.dRPreshowerPreselection);
390 
391  LogTrace("TrackAssociator") << "Number of Preshower Ids in the region: " << idsInRegion.size();
392  info.crossedPreshowerIds = preshowerDetIdAssociator_->getCrossedDetIds(idsInRegion, trajectory);
393  LogTrace("TrackAssociator") << "Number of Preshower Ids in crossed: " << info.crossedPreshowerIds.size();
394 }
395 
399  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getHcalTrajectory();
400 
401  std::vector<GlobalPoint> coreTrajectory;
402  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
403  itr != trajectoryStates.end();
404  itr++)
405  coreTrajectory.push_back(itr->position());
406 
407  if (coreTrajectory.empty()) {
408  LogTrace("TrackAssociator") << "HCAL trajectory is empty; moving on\n";
409  info.isGoodHcal = false;
410  return;
411  }
412  info.isGoodHcal = true;
413 
414  // find crossed Hcals
416  iEvent.getByToken(parameters.HBHEcollToken, collection);
417  if (!collection.isValid())
418  throw cms::Exception("FatalError") << "Unable to find HBHERecHits in event!\n";
419 
420  std::set<DetId> idsInRegion;
421  if (parameters.accountForTrajectoryChangeCalo) {
422  // get trajectory change with respect to initial state
423  DetIdAssociator::MapRange mapRange =
424  getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHcal), parameters.dRHcalPreselection);
425  idsInRegion = hcalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
426  } else
427  idsInRegion = hcalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dRHcalPreselection);
428 
429  LogTrace("TrackAssociator") << "HCAL hits in the region: " << idsInRegion.size() << "\n"
430  << DetIdInfo::info(idsInRegion, nullptr);
431 
432  auto idsInAConeBegin = idsInRegion.begin();
433  auto idsInAConeEnd = idsInRegion.end();
434  std::set<DetId> idsInAConeTmp;
435  if (!hcalDetIdAssociator_->selectAllInACone(parameters.dRHcal)) {
436  idsInAConeTmp = hcalDetIdAssociator_->getDetIdsInACone(idsInRegion, coreTrajectory, parameters.dRHcal);
437  idsInAConeBegin = idsInAConeTmp.begin();
438  idsInAConeEnd = idsInAConeTmp.end();
439  }
440  LogTrace("TrackAssociator") << "HCAL hits in the cone: " << std::distance(idsInAConeBegin, idsInAConeEnd) << "\n"
441  << DetIdInfo::info(std::set<DetId>(idsInAConeBegin, idsInAConeEnd), nullptr);
442  info.crossedHcalIds = hcalDetIdAssociator_->getCrossedDetIds(idsInRegion, coreTrajectory);
443  const std::vector<DetId>& crossedIds = info.crossedHcalIds;
444  LogTrace("TrackAssociator") << "HCAL hits crossed: " << crossedIds.size() << "\n"
445  << DetIdInfo::info(crossedIds, nullptr);
446 
447  // add Hcal
448  for (std::vector<DetId>::const_iterator itr = crossedIds.begin(); itr != crossedIds.end(); itr++) {
449  HBHERecHitCollection::const_iterator hit = (*collection).find(*itr);
450  if (hit != (*collection).end())
451  info.crossedHcalRecHits.push_back(&*hit);
452  else
453  LogTrace("TrackAssociator") << "Crossed HBHERecHit is not found for DetId: " << itr->rawId();
454  }
455  for (std::set<DetId>::const_iterator itr = idsInAConeBegin; itr != idsInAConeEnd; itr++) {
456  HBHERecHitCollection::const_iterator hit = (*collection).find(*itr);
457  if (hit != (*collection).end())
458  info.hcalRecHits.push_back(&*hit);
459  else
460  LogTrace("TrackAssociator") << "HBHERecHit from the cone is not found for DetId: " << itr->rawId();
461  }
462 }
463 
467  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getHOTrajectory();
468 
469  std::vector<GlobalPoint> coreTrajectory;
470  for (std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
471  itr != trajectoryStates.end();
472  itr++)
473  coreTrajectory.push_back(itr->position());
474 
475  if (coreTrajectory.empty()) {
476  LogTrace("TrackAssociator") << "HO trajectory is empty; moving on\n";
477  info.isGoodHO = false;
478  return;
479  }
480  info.isGoodHO = true;
481 
482  // find crossed HOs
484  iEvent.getByToken(parameters.HOcollToken, collection);
485  if (!collection.isValid())
486  throw cms::Exception("FatalError") << "Unable to find HORecHits in event!\n";
487 
488  std::set<DetId> idsInRegion;
489  if (parameters.accountForTrajectoryChangeCalo) {
490  // get trajectory change with respect to initial state
491  DetIdAssociator::MapRange mapRange =
492  getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHO), parameters.dRHcalPreselection);
493  idsInRegion = hoDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
494  } else
495  idsInRegion = hoDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dRHcalPreselection);
496 
497  LogTrace("TrackAssociator") << "idsInRegion.size(): " << idsInRegion.size();
498 
499  auto idsInAConeBegin = idsInRegion.begin();
500  auto idsInAConeEnd = idsInRegion.end();
501  std::set<DetId> idsInAConeTmp;
502  if (!hoDetIdAssociator_->selectAllInACone(parameters.dRHcal)) {
503  idsInAConeTmp = hoDetIdAssociator_->getDetIdsInACone(idsInRegion, coreTrajectory, parameters.dRHcal);
504  idsInAConeBegin = idsInAConeTmp.begin();
505  idsInAConeEnd = idsInAConeTmp.end();
506  }
507  LogTrace("TrackAssociator") << "idsInACone.size(): " << std::distance(idsInAConeBegin, idsInAConeEnd);
508  info.crossedHOIds = hoDetIdAssociator_->getCrossedDetIds(idsInRegion, coreTrajectory);
509  const std::vector<DetId>& crossedIds = info.crossedHOIds;
510 
511  // add HO
512  for (std::vector<DetId>::const_iterator itr = crossedIds.begin(); itr != crossedIds.end(); itr++) {
513  HORecHitCollection::const_iterator hit = (*collection).find(*itr);
514  if (hit != (*collection).end())
515  info.crossedHORecHits.push_back(&*hit);
516  else
517  LogTrace("TrackAssociator") << "Crossed HORecHit is not found for DetId: " << itr->rawId();
518  }
519 
520  for (std::set<DetId>::const_iterator itr = idsInAConeBegin; itr != idsInAConeEnd; itr++) {
521  HORecHitCollection::const_iterator hit = (*collection).find(*itr);
522  if (hit != (*collection).end())
523  info.hoRecHits.push_back(&*hit);
524  else
525  LogTrace("TrackAssociator") << "HORecHit from the cone is not found for DetId: " << itr->rawId();
526  }
527 }
528 
530  const SimTrack& track,
531  const SimVertex& vertex) {
532  GlobalVector vector(track.momentum().x(), track.momentum().y(), track.momentum().z());
533  GlobalPoint point(vertex.position().x(), vertex.position().y(), vertex.position().z());
534 
535  int charge = track.type() > 0 ? -1 : 1; // lepton convention
536  if (abs(track.type()) == 211 || // pion
537  abs(track.type()) == 321 || // kaon
538  abs(track.type()) == 2212)
539  charge = track.type() < 0 ? -1 : 1;
540  return getFreeTrajectoryState(bField, vector, point, charge);
541 }
542 
544  const GlobalVector& momentum,
545  const GlobalPoint& vertex,
546  const int charge) {
547  GlobalTrajectoryParameters tPars(vertex, momentum, charge, bField);
548 
549  ROOT::Math::SMatrixIdentity id;
550  AlgebraicSymMatrix66 covT(id);
551  covT *= 1e-6; // initialize to sigma=1e-3
552  CartesianTrajectoryError tCov(covT);
553 
554  return FreeTrajectoryState(tPars, tCov);
555 }
556 
558  const reco::Track& track) {
559  GlobalVector vector(track.momentum().x(), track.momentum().y(), track.momentum().z());
560 
561  GlobalPoint point(track.vertex().x(), track.vertex().y(), track.vertex().z());
562 
564 
565  // FIX THIS !!!
566  // need to convert from perigee to global or helix (curvilinear) frame
567  // for now just an arbitrary matrix.
568  ROOT::Math::SMatrixIdentity id;
569  AlgebraicSymMatrix66 covT(id);
570  covT *= 1e-6; // initialize to sigma=1e-3
571  CartesianTrajectoryError tCov(covT);
572 
573  return FreeTrajectoryState(tPars, tCov);
574 }
575 
576 DetIdAssociator::MapRange TrackDetectorAssociator::getMapRange(const std::pair<float, float>& delta, const float dR) {
577  DetIdAssociator::MapRange mapRange;
578  mapRange.dThetaPlus = dR;
579  mapRange.dThetaMinus = dR;
580  mapRange.dPhiPlus = dR;
581  mapRange.dPhiMinus = dR;
582  if (delta.first > 0)
583  mapRange.dThetaPlus += delta.first;
584  else
585  mapRange.dThetaMinus += std::abs(delta.first);
586  if (delta.second > 0)
587  mapRange.dPhiPlus += delta.second;
588  else
589  mapRange.dPhiMinus += std::abs(delta.second);
590  LogTrace("TrackAssociator") << "Selection range: (dThetaPlus, dThetaMinus, dPhiPlus, dPhiMinus, dRPreselection): "
591  << mapRange.dThetaPlus << ", " << mapRange.dThetaMinus << ", " << mapRange.dPhiPlus
592  << ", " << mapRange.dPhiMinus << ", " << dR;
593  return mapRange;
594 }
595 
596 void TrackDetectorAssociator::getTAMuonChamberMatches(std::vector<TAMuonChamberMatch>& matches,
598  std::set<DetId> occupancy) {
599  // Strategy:
600  // Propagate through the whole detector, estimate change in eta and phi
601  // along the trajectory, add this to dRMuon and find DetIds around this
602  // direction using the map. Then propagate fast to each surface and apply
603  // final matching criteria.
604 
605  // get the direction first
606  SteppingHelixStateInfo trajectoryPoint = cachedTrajectory_.getStateAtHcal();
607  // If trajectory point at HCAL is not valid, try to use the outer most state of the
608  // trajectory instead.
609  if (!trajectoryPoint.isValid())
610  trajectoryPoint = cachedTrajectory_.getOuterState();
611  if (!trajectoryPoint.isValid()) {
612  LogTrace("TrackAssociator")
613  << "trajectory position at HCAL is not valid. Assume the track cannot reach muon detectors and skip it";
614  return;
615  }
616 
617  GlobalVector direction = trajectoryPoint.momentum().unit();
618  LogTrace("TrackAssociator") << "muon direction: " << direction
619  << "\n\t and corresponding point: " << trajectoryPoint.position() << "\n";
620 
621  DetIdAssociator::MapRange mapRange =
622  getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::FullTrajectory), parameters.dRMuonPreselection);
623 
624  // and find chamber DetIds
625 
626  std::set<DetId> muonIdsInRegion = muonDetIdAssociator_->getDetIdsCloseToAPoint(trajectoryPoint.position(), mapRange);
627  LogTrace("TrackAssociator") << "Number of chambers to check: " << muonIdsInRegion.size();
628 
629  if (parameters.preselectMuonTracks) {
630  std::set<DetId> muonIdsInRegionOccupied;
631  std::set_intersection(muonIdsInRegion.begin(),
632  muonIdsInRegion.end(),
633  occupancy.begin(),
634  occupancy.end(),
635  std::inserter(muonIdsInRegionOccupied, muonIdsInRegionOccupied.begin()));
636  if (muonIdsInRegionOccupied.empty())
637  return;
638  }
639 
640  for (std::set<DetId>::const_iterator detId = muonIdsInRegion.begin(); detId != muonIdsInRegion.end(); detId++) {
641  const GeomDet* geomDet = muonDetIdAssociator_->getGeomDet(*detId);
642  TrajectoryStateOnSurface stateOnSurface = cachedTrajectory_.propagate(&geomDet->surface());
643  if (!stateOnSurface.isValid()) {
644  LogTrace("TrackAssociator") << "Failed to propagate the track; moving on\n\t"
645  << "Element is not crosssed: " << DetIdInfo::info(*detId, nullptr) << "\n";
646  continue;
647  }
648  LocalPoint localPoint = geomDet->surface().toLocal(stateOnSurface.freeState()->position());
649  LocalError localError = stateOnSurface.localError().positionError();
650  float distanceX = 0.f;
651  float distanceY = 0.f;
652  if (const CSCChamber* cscChamber = dynamic_cast<const CSCChamber*>(geomDet)) {
653  const CSCChamberSpecs* chamberSpecs = cscChamber->specs();
654  if (!chamberSpecs) {
655  LogTrace("TrackAssociator") << "Failed to get CSCChamberSpecs from CSCChamber; moving on\n";
656  continue;
657  }
658  const CSCLayerGeometry* layerGeometry = chamberSpecs->oddLayerGeometry(1);
659  if (!layerGeometry) {
660  LogTrace("TrackAssociator") << "Failed to get CSCLayerGeometry from CSCChamberSpecs; moving on\n";
661  continue;
662  }
663  const CSCWireTopology* wireTopology = layerGeometry->wireTopology();
664  if (!wireTopology) {
665  LogTrace("TrackAssociator") << "Failed to get CSCWireTopology from CSCLayerGeometry; moving on\n";
666  continue;
667  }
668 
669  float wideWidth = wireTopology->wideWidthOfPlane();
670  float narrowWidth = wireTopology->narrowWidthOfPlane();
671  float length = wireTopology->lengthOfPlane();
672  // If slanted, there is no y offset between local origin and symmetry center of wire plane
673  float yOfFirstWire = std::abs(wireTopology->wireAngle()) > 1.E-06f ? -0.5 * length : wireTopology->yOfWire(1);
674  // y offset between local origin and symmetry center of wire plane
675  float yCOWPOffset = yOfFirstWire + 0.5f * length;
676 
677  // tangent of the incline angle from inside the trapezoid
678  float tangent = (wideWidth - narrowWidth) / (2.f * length);
679  // y position wrt bottom of trapezoid
680  float yPrime = localPoint.y() + std::abs(yOfFirstWire);
681  // half trapezoid width at y' is 0.5 * narrowWidth + x side of triangle with the above tangent and side y'
682  float halfWidthAtYPrime = 0.5f * narrowWidth + yPrime * tangent;
683  distanceX = std::abs(localPoint.x()) - halfWidthAtYPrime;
684  distanceY = std::abs(localPoint.y() - yCOWPOffset) - 0.5f * length;
685  } else if (dynamic_cast<const GEMChamber*>(geomDet) || dynamic_cast<const GEMSuperChamber*>(geomDet)) {
686  const TrapezoidalPlaneBounds* bounds = dynamic_cast<const TrapezoidalPlaneBounds*>(&geomDet->surface().bounds());
687 
688  float wideWidth = bounds->width();
689  float narrowWidth = 2.f * bounds->widthAtHalfLength() - wideWidth;
690  float length = bounds->length();
691  float tangent = (wideWidth - narrowWidth) / (2.f * length);
692  float halfWidthAtY = tangent * localPoint.y() + 0.25f * (narrowWidth + wideWidth);
693 
694  distanceX = std::abs(localPoint.x()) - halfWidthAtY;
695  distanceY = std::abs(localPoint.y()) - 0.5f * length;
696  } else {
697  distanceX = std::abs(localPoint.x()) - 0.5f * geomDet->surface().bounds().width();
698  distanceY = std::abs(localPoint.y()) - 0.5f * geomDet->surface().bounds().length();
699  }
700  if ((distanceX < parameters.muonMaxDistanceX && distanceY < parameters.muonMaxDistanceY) ||
701  (distanceX * distanceX <
702  localError.xx() * parameters.muonMaxDistanceSigmaX * parameters.muonMaxDistanceSigmaX &&
703  distanceY * distanceY <
704  localError.yy() * parameters.muonMaxDistanceSigmaY * parameters.muonMaxDistanceSigmaY)) {
705  LogTrace("TrackAssociator") << "found a match: " << DetIdInfo::info(*detId, nullptr) << "\n";
706  TAMuonChamberMatch match;
707  match.tState = stateOnSurface;
708  match.localDistanceX = distanceX;
709  match.localDistanceY = distanceY;
710  match.id = *detId;
711  matches.push_back(match);
712  } else {
713  LogTrace("TrackAssociator") << "chamber is too far: " << DetIdInfo::info(*detId, nullptr)
714  << "\n\tdistanceX: " << distanceX << "\t distanceY: " << distanceY
715  << "\t sigmaX: " << distanceX / sqrt(localError.xx())
716  << "\t sigmaY: " << distanceY / sqrt(localError.yy()) << "\n";
717  }
718  }
719 }
720 
724  // Get the segments from the event
726  iEvent.getByToken(parameters.dtSegmentsToken, dtSegments);
727  if (!dtSegments.isValid())
728  throw cms::Exception("FatalError") << "Unable to find DTRecSegment4DCollection in event!\n";
729 
731  iEvent.getByToken(parameters.cscSegmentsToken, cscSegments);
732  if (!cscSegments.isValid())
733  throw cms::Exception("FatalError") << "Unable to find CSCSegmentCollection in event!\n";
734 
736  if (parameters.useGEM)
737  iEvent.getByToken(parameters.gemSegmentsToken, gemSegments);
739  if (parameters.useME0)
740  iEvent.getByToken(parameters.me0SegmentsToken, me0Segments);
741 
742  // Get the hits from the event only if track preselection is activated
743  // Get the chambers segments/hits in the events
744  std::set<DetId> occupancy_set;
745  if (parameters.preselectMuonTracks) {
747  iEvent.getByToken(parameters.rpcHitsToken, rpcRecHits);
748  if (!rpcRecHits.isValid())
749  throw cms::Exception("FatalError") << "Unable to find RPCRecHitCollection in event!\n";
750 
752  if (parameters.useGEM)
753  iEvent.getByToken(parameters.gemHitsToken, gemRecHits);
754 
756  if (parameters.useME0)
757  iEvent.getByToken(parameters.me0HitsToken, me0RecHits);
758 
759  for (const auto& dtSegment : *dtSegments) {
760  occupancy_set.insert(dtSegment.geographicalId());
761  }
762  for (const auto& cscSegment : *cscSegments) {
763  occupancy_set.insert(cscSegment.geographicalId());
764  }
765  for (const auto& rpcRecHit : *rpcRecHits) {
766  occupancy_set.insert(rpcRecHit.geographicalId());
767  }
768  if (parameters.useGEM) {
769  for (const auto& gemSegment : *gemSegments) {
770  occupancy_set.insert(gemSegment.geographicalId());
771  }
772  for (const auto& gemRecHit : *gemRecHits) {
773  occupancy_set.insert(gemRecHit.geographicalId());
774  }
775  }
776  if (parameters.useME0) {
777  for (const auto& me0Segment : *me0Segments) {
778  occupancy_set.insert(me0Segment.geographicalId());
779  }
780  for (const auto& me0RecHit : *me0RecHits) {
781  occupancy_set.insert(me0RecHit.geographicalId());
782  }
783  }
784  if (occupancy_set.empty()) {
785  LogTrace("TrackAssociator") << "No segments or hits were found in the event: aborting track extrapolation"
786  << std::endl;
787  return;
788  }
789  }
790 
792 
793  // check the map of available segments
794  // if there is no segments in a given direction at all,
795  // then there is no point to fly there.
796  //
797  // MISSING
798  // Possible solution: quick search for presence of segments
799  // for the set of DetIds
800 
801  // get a set of matches corresponding to muon chambers
802  std::vector<TAMuonChamberMatch> matchedChambers;
803  LogTrace("TrackAssociator") << "Trying to Get ChamberMatches" << std::endl;
804  getTAMuonChamberMatches(matchedChambers, parameters, occupancy_set);
805  LogTrace("TrackAssociator") << "Chambers matched: " << matchedChambers.size() << "\n";
806 
807  // Iterate over all chamber matches and fill segment matching
808  // info if it's available
809  for (std::vector<TAMuonChamberMatch>::iterator matchedChamber = matchedChambers.begin();
810  matchedChamber != matchedChambers.end();
811  matchedChamber++) {
812  const GeomDet* geomDet = muonDetIdAssociator_->getGeomDet((*matchedChamber).id);
813  // DT chamber
814  if (const DTChamber* chamber = dynamic_cast<const DTChamber*>(geomDet)) {
815  // Get the range for the corresponding segments
816  DTRecSegment4DCollection::range range = dtSegments->get(chamber->id());
817  // Loop over the segments of this chamber
818  for (DTRecSegment4DCollection::const_iterator segment = range.first; segment != range.second; segment++) {
819  if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
820  matchedChamber->segments.back().dtSegmentRef = DTRecSegment4DRef(dtSegments, segment - dtSegments->begin());
821  }
822  }
823  }
824  // CSC Chamber
825  else if (const CSCChamber* chamber = dynamic_cast<const CSCChamber*>(geomDet)) {
826  // Get the range for the corresponding segments
828  // Loop over the segments
829  for (CSCSegmentCollection::const_iterator segment = range.first; segment != range.second; segment++) {
830  if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
831  matchedChamber->segments.back().cscSegmentRef = CSCSegmentRef(cscSegments, segment - cscSegments->begin());
832  }
833  }
834  } else {
835  // GEM Chamber
836  if (parameters.useGEM) {
837  if (const GEMSuperChamber* chamber = dynamic_cast<const GEMSuperChamber*>(geomDet)) {
838  // Get the range for the corresponding segments
839  GEMSegmentCollection::range range = gemSegments->get(chamber->id());
840  // Loop over the segments
841  for (GEMSegmentCollection::const_iterator segment = range.first; segment != range.second; segment++) {
842  if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
843  matchedChamber->segments.back().gemSegmentRef =
844  GEMSegmentRef(gemSegments, segment - gemSegments->begin());
845  }
846  }
847  }
848  }
849  // ME0 Chamber
850  if (parameters.useME0) {
851  if (const ME0Chamber* chamber = dynamic_cast<const ME0Chamber*>(geomDet)) {
852  // Get the range for the corresponding segments
854  // Loop over the segments
855  for (ME0SegmentCollection::const_iterator segment = range.first; segment != range.second; segment++) {
856  if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
857  matchedChamber->segments.back().me0SegmentRef =
858  ME0SegmentRef(me0Segments, segment - me0Segments->begin());
859  }
860  }
861  }
862  }
863  }
864  info.chambers.push_back(*matchedChamber);
865  }
866 }
867 
869  const RecSegment* segment,
871  LogTrace("TrackAssociator") << "Segment local position: " << segment->localPosition() << "\n"
872  << std::hex << segment->geographicalId().rawId() << "\n";
873 
874  const GeomDet* chamber = muonDetIdAssociator_->getGeomDet(matchedChamber.id);
875  TrajectoryStateOnSurface trajectoryStateOnSurface = matchedChamber.tState;
876  GlobalPoint segmentGlobalPosition = chamber->toGlobal(segment->localPosition());
877 
878  LogTrace("TrackAssociator") << "Segment global position: " << segmentGlobalPosition
879  << " \t (R_xy,eta,phi): " << segmentGlobalPosition.perp() << ","
880  << segmentGlobalPosition.eta() << "," << segmentGlobalPosition.phi() << "\n";
881 
882  LogTrace("TrackAssociator") << "\teta hit: " << segmentGlobalPosition.eta()
883  << " \tpropagator: " << trajectoryStateOnSurface.freeState()->position().eta() << "\n"
884  << "\tphi hit: " << segmentGlobalPosition.phi()
885  << " \tpropagator: " << trajectoryStateOnSurface.freeState()->position().phi()
886  << std::endl;
887 
888  bool isGood = false;
889  bool isDTWithoutY = false;
890  const DTRecSegment4D* dtseg = dynamic_cast<const DTRecSegment4D*>(segment);
891  if (dtseg && (!dtseg->hasZed()))
892  isDTWithoutY = true;
893 
894  float deltaPhi(std::abs(segmentGlobalPosition.phi() - trajectoryStateOnSurface.freeState()->position().phi()));
895  if (deltaPhi > float(M_PI))
896  deltaPhi = std::abs(deltaPhi - float(M_PI) * 2.f);
897  float deltaEta = std::abs(segmentGlobalPosition.eta() - trajectoryStateOnSurface.freeState()->position().eta());
898 
899  if (isDTWithoutY) {
900  isGood = deltaPhi < parameters.dRMuon;
901  // Be in chamber
902  isGood &= deltaEta < .3f;
903  } else
904  isGood = deltaEta * deltaEta + deltaPhi * deltaPhi < parameters.dRMuon * parameters.dRMuon;
905 
906  if (isGood) {
907  TAMuonSegmentMatch muonSegment;
908  muonSegment.segmentGlobalPosition = getPoint(segmentGlobalPosition);
909  muonSegment.segmentLocalPosition = getPoint(segment->localPosition());
910  muonSegment.segmentLocalDirection = getVector(segment->localDirection());
911  muonSegment.segmentLocalErrorXX = segment->localPositionError().xx();
912  muonSegment.segmentLocalErrorYY = segment->localPositionError().yy();
913  muonSegment.segmentLocalErrorXY = segment->localPositionError().xy();
914  muonSegment.segmentLocalErrorDxDz = segment->localDirectionError().xx();
915  muonSegment.segmentLocalErrorDyDz = segment->localDirectionError().yy();
916 
917  // DANGEROUS - compiler cannot guaranty parameters ordering
918  // AlgebraicSymMatrix segmentCovMatrix = segment->parametersError();
919  // muonSegment.segmentLocalErrorXDxDz = segmentCovMatrix[2][0];
920  // muonSegment.segmentLocalErrorYDyDz = segmentCovMatrix[3][1];
921  muonSegment.segmentLocalErrorXDxDz = -999.f;
922  muonSegment.segmentLocalErrorYDyDz = -999.f;
923  muonSegment.hasZed = true;
924  muonSegment.hasPhi = true;
925 
926  // timing information
927  muonSegment.t0 = 0.f;
928  if (dtseg) {
929  if ((dtseg->hasPhi()) && (!isDTWithoutY)) {
930  int phiHits = dtseg->phiSegment()->specificRecHits().size();
931  // int zHits = dtseg->zSegment()->specificRecHits().size();
932  int hits = 0;
933  double t0 = 0.;
934  // TODO: cuts on hit numbers not optimized in any way yet...
935  if (phiHits > 5 && dtseg->phiSegment()->ist0Valid()) {
936  t0 += dtseg->phiSegment()->t0() * phiHits;
937  hits += phiHits;
938  LogTrace("TrackAssociator") << " Phi t0: " << dtseg->phiSegment()->t0() << " hits: " << phiHits;
939  }
940  // the z segments seem to contain little useful information...
941  // if (zHits>3) {
942  // t0+=s->zSegment()->t0()*zHits;
943  // hits+=zHits;
944  // LogTrace("TrackAssociator") << " Z t0: " << s->zSegment()->t0() << " hits: " << zHits << std::endl;
945  // }
946  if (hits)
947  muonSegment.t0 = t0 / hits;
948  // LogTrace("TrackAssociator") << " --- t0: " << muonSegment.t0 << std::endl;
949  } else {
950  // check and set dimensionality
951  if (isDTWithoutY)
952  muonSegment.hasZed = false;
953  if (!dtseg->hasPhi())
954  muonSegment.hasPhi = false;
955  }
956  }
957  matchedChamber.segments.push_back(muonSegment);
958  }
959 
960  return isGood;
961 }
962 
963 //********************** NON-CORE CODE ******************************//
964 
968  // get list of simulated tracks and their vertices
969  using namespace edm;
971  iEvent.getByToken(parameters.simTracksToken, simTracks);
972  if (!simTracks.isValid())
973  throw cms::Exception("FatalError") << "No simulated tracks found\n";
974 
976  iEvent.getByToken(parameters.simVerticesToken, simVertices);
977  if (!simVertices.isValid())
978  throw cms::Exception("FatalError") << "No simulated vertices found\n";
979 
980  // get sim calo hits
981  Handle<PCaloHitContainer> simEcalHitsEB;
982  iEvent.getByToken(parameters.simEcalHitsEBToken, simEcalHitsEB);
983  if (!simEcalHitsEB.isValid())
984  throw cms::Exception("FatalError") << "No simulated ECAL EB hits found\n";
985 
986  Handle<PCaloHitContainer> simEcalHitsEE;
987  iEvent.getByToken(parameters.simEcalHitsEEToken, simEcalHitsEE);
988  if (!simEcalHitsEE.isValid())
989  throw cms::Exception("FatalError") << "No simulated ECAL EE hits found\n";
990 
991  Handle<PCaloHitContainer> simHcalHits;
992  iEvent.getByToken(parameters.simHcalHitsToken, simHcalHits);
993  if (!simHcalHits.isValid())
994  throw cms::Exception("FatalError") << "No simulated HCAL hits found\n";
995 
996  // find truth partner
997  SimTrackContainer::const_iterator simTrack = simTracks->begin();
998  for (; simTrack != simTracks->end(); ++simTrack) {
999  math::XYZVector simP3(simTrack->momentum().x(), simTrack->momentum().y(), simTrack->momentum().z());
1000  math::XYZVector recoP3(info.stateAtIP.momentum().x(), info.stateAtIP.momentum().y(), info.stateAtIP.momentum().z());
1001  if (ROOT::Math::VectorUtil::DeltaR(recoP3, simP3) < 0.1)
1002  break;
1003  }
1004  if (simTrack != simTracks->end()) {
1005  info.simTrack = &(*simTrack);
1006  float ecalTrueEnergy(0);
1007  float hcalTrueEnergy(0);
1008 
1009  // loop over calo hits
1010  for (PCaloHitContainer::const_iterator hit = simEcalHitsEB->begin(); hit != simEcalHitsEB->end(); ++hit)
1011  if (hit->geantTrackId() == info.simTrack->genpartIndex())
1012  ecalTrueEnergy += hit->energy();
1013 
1014  for (PCaloHitContainer::const_iterator hit = simEcalHitsEE->begin(); hit != simEcalHitsEE->end(); ++hit)
1015  if (hit->geantTrackId() == info.simTrack->genpartIndex())
1016  ecalTrueEnergy += hit->energy();
1017 
1018  for (PCaloHitContainer::const_iterator hit = simHcalHits->begin(); hit != simHcalHits->end(); ++hit)
1019  if (hit->geantTrackId() == info.simTrack->genpartIndex())
1020  hcalTrueEnergy += hit->energy();
1021 
1022  info.ecalTrueEnergy = ecalTrueEnergy;
1023  info.hcalTrueEnergy = hcalTrueEnergy;
1024  info.hcalTrueEnergyCorrected = hcalTrueEnergy;
1025  if (std::abs(info.trkGlobPosAtHcal.eta()) < 1.3f)
1026  info.hcalTrueEnergyCorrected = hcalTrueEnergy * 113.2f;
1027  else if (std::abs(info.trkGlobPosAtHcal.eta()) < 3.0f)
1028  info.hcalTrueEnergyCorrected = hcalTrueEnergy * 167.2f;
1029  }
1030 }
1031 
1033  const edm::EventSetup& iSetup,
1034  const reco::Track& track,
1036  Direction direction /*= Any*/) {
1037  double currentStepSize = cachedTrajectory_.getPropagationStep();
1038 
1039  const MagneticField* bField = &iSetup.getData(parameters.bFieldToken);
1040 
1041  if (track.extra().isNull()) {
1042  if (direction != InsideOut)
1043  throw cms::Exception("FatalError") << "No TrackExtra information is available and association is done with "
1044  "something else than InsideOut track.\n"
1045  << "Either change the parameter or provide needed data!\n";
1046  LogTrace("TrackAssociator") << "Track Extras not found\n";
1048  return associate(iEvent, iSetup, parameters, &initialState); // 5th argument is null pointer
1049  }
1050 
1051  LogTrace("TrackAssociator") << "Track Extras found\n";
1055 
1056  LogTrace("TrackAssociator") << "inner track state (rho, z, phi):" << track.innerPosition().Rho() << ", "
1057  << track.innerPosition().z() << ", " << track.innerPosition().phi() << "\n";
1058  LogTrace("TrackAssociator") << "innerFreeState (rho, z, phi):" << innerState.position().perp() << ", "
1059  << innerState.position().z() << ", " << innerState.position().phi() << "\n";
1060 
1061  LogTrace("TrackAssociator") << "outer track state (rho, z, phi):" << track.outerPosition().Rho() << ", "
1062  << track.outerPosition().z() << ", " << track.outerPosition().phi() << "\n";
1063  LogTrace("TrackAssociator") << "outerFreeState (rho, z, phi):" << outerState.position().perp() << ", "
1064  << outerState.position().z() << ", " << outerState.position().phi() << "\n";
1065 
1066  // InsideOut first
1067  if (crossedIP(track)) {
1068  switch (direction) {
1069  case InsideOut:
1070  case Any:
1071  return associate(iEvent, iSetup, parameters, &referenceState, &outerState);
1072  break;
1073  case OutsideIn: {
1074  cachedTrajectory_.setPropagationStep(-std::abs(currentStepSize));
1075  TrackDetMatchInfo result = associate(iEvent, iSetup, parameters, &innerState, &referenceState);
1076  cachedTrajectory_.setPropagationStep(currentStepSize);
1077  return result;
1078  break;
1079  }
1080  }
1081  } else {
1082  switch (direction) {
1083  case InsideOut:
1084  return associate(iEvent, iSetup, parameters, &innerState, &outerState);
1085  break;
1086  case OutsideIn: {
1087  cachedTrajectory_.setPropagationStep(-std::abs(currentStepSize));
1088  TrackDetMatchInfo result = associate(iEvent, iSetup, parameters, &outerState, &innerState);
1089  cachedTrajectory_.setPropagationStep(currentStepSize);
1090  return result;
1091  break;
1092  }
1093  case Any: {
1094  // check if we deal with clear outside-in case
1095  if (track.innerPosition().Dot(track.innerMomentum()) < 0 &&
1096  track.outerPosition().Dot(track.outerMomentum()) < 0) {
1097  cachedTrajectory_.setPropagationStep(-std::abs(currentStepSize));
1099  if (track.innerPosition().Mag2() < track.outerPosition().Mag2())
1100  result = associate(iEvent, iSetup, parameters, &innerState, &outerState);
1101  else
1102  result = associate(iEvent, iSetup, parameters, &outerState, &innerState);
1103  cachedTrajectory_.setPropagationStep(currentStepSize);
1104  return result;
1105  }
1106  }
1107  }
1108  }
1109 
1110  // all other cases
1111  return associate(iEvent, iSetup, parameters, &innerState, &outerState);
1112 }
1113 
1115  const edm::EventSetup& iSetup,
1116  const SimTrack& track,
1117  const SimVertex& vertex,
1119  auto const* bField = &iSetup.getData(parameters.bFieldToken);
1120  return associate(iEvent, iSetup, getFreeTrajectoryState(bField, track, vertex), parameters);
1121 }
1122 
1124  const edm::EventSetup& iSetup,
1125  const GlobalVector& momentum,
1126  const GlobalPoint& vertex,
1127  const int charge,
1129  auto const* bField = &iSetup.getData(parameters.bFieldToken);
1130  return associate(iEvent, iSetup, getFreeTrajectoryState(bField, momentum, vertex, charge), parameters);
1131 }
1132 
1134  bool crossed = true;
1135  crossed &= (track.innerPosition().rho() > 3); // something close to active volume
1136  crossed &= (track.outerPosition().rho() > 3); // something close to active volume
1137  crossed &=
1138  ((track.innerPosition().x() * track.innerMomentum().x() + track.innerPosition().y() * track.innerMomentum().y() <
1139  0) !=
1140  (track.outerPosition().x() * track.outerMomentum().x() + track.outerPosition().y() * track.outerMomentum().y() <
1141  0));
1142  return crossed;
1143 }
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
bool ist0Valid() const
static const TGPicture * info(bool iBackgroundIsBlack)
T perp() const
Definition: PV3DBase.h:69
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
virtual float length() const =0
static bool crossedIP(const reco::Track &track)
double wideWidthOfPlane() const
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
const LocalTrajectoryError & localError() const
virtual LocalError localDirectionError() const =0
Error on the local direction.
TrajectoryStateOnSurface tState
bool hasPhi() const
Does it have the Phi projection?
float width() const override
const CSCWireTopology * wireTopology() const
double t0() const
Get the segment t0 (if recomputed, 0 is returned otherwise)
T z() const
Definition: PV3DBase.h:61
math::XYZPoint segmentGlobalPosition
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
edm::Ref< CSCSegmentCollection > CSCSegmentRef
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
edm::Ref< ME0SegmentCollection > ME0SegmentRef
math::XYZPoint segmentLocalPosition
virtual LocalVector localDirection() const =0
Local direction.
T eta() const
Definition: PV3DBase.h:73
void useDefaultPropagator()
use the default propagator
std::vector< CaloTower >::const_iterator const_iterator
void fillHcal(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
bool addTAMuonSegmentMatch(TAMuonChamberMatch &, const RecSegment *, const AssociatorParameters &)
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float charge(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:73
LocalError positionError() const
LocalPoint toLocal(const GlobalPoint &gp) const
math::XYZVector segmentLocalDirection
static const double deltaEta
Definition: CaloConstants.h:8
#define LogTrace(id)
GlobalPoint position() const
void fillCaloTowers(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
GlobalPoint position() const
void fillCaloTruth(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
C::const_iterator const_iterator
constant access iterator type
Definition: RangeMap.h:43
float yy() const
Definition: LocalError.h:24
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
void init(const edm::EventSetup &, const AssociatorParameters &)
float wireAngle() const override
int iEvent
Definition: GenABIO.cc:224
void setPropagator(const Propagator *)
use a user configured propagator
T sqrt(T t)
Definition: SSEVec.h:19
edm::Ref< GEMSegmentCollection > GEMSegmentRef
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
std::vector< TAMuonSegmentMatch > segments
distance sign convention: negative - crossed chamber, positive - missed chamber
void getTAMuonChamberMatches(std::vector< TAMuonChamberMatch > &matches, const AssociatorParameters &parameters, std::set< DetId > occupancy)
T mag() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE void init(ZVertexSoAView &vertices)
Definition: ZVertexSoA.h:25
void fillPreshower(const edm::Event &iEvent, TrackDetMatchInfo &info, const AssociatorParameters &)
#define M_PI
edm::Ref< DTRecSegment4DCollection > DTRecSegment4DRef
ROOT::Math::SMatrix< double, 6, 6, ROOT::Math::MatRepSym< double, 6 > > AlgebraicSymMatrix66
float xy() const
Definition: LocalError.h:23
float yOfWire(float wire, float x=0.) const
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
DetId geographicalId() const
const DTChamberRecSegment2D * phiSegment() const
The superPhi segment: 0 if no phi projection available.
const CSCLayerGeometry * oddLayerGeometry(int iendcap) const
Accessors for LayerGeometry&#39;s.
std::vector< DTRecHit1D > specificRecHits() const
Access to specific components.
static std::string info(const DetId &, const TrackerTopology *tTopo)
Definition: DetIdInfo.cc:25
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
virtual LocalError localPositionError() const =0
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
void fillMuon(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
double lengthOfPlane() const
static FreeTrajectoryState getFreeTrajectoryState(const MagneticField *, const reco::Track &)
get FreeTrajectoryState from different track representations
bool isValid() const
Definition: HandleBase.h:70
DetIdAssociator::MapRange getMapRange(const std::pair< float, float > &delta, const float dR)
double narrowWidthOfPlane() const
GlobalVector momentum() const
fixed size matrix
HLT enums.
void fillEcal(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
TrackDetMatchInfo associate(const edm::Event &, const edm::EventSetup &, const FreeTrajectoryState &, const AssociatorParameters &)
FreeTrajectoryState const * freeState(bool withErrors=true) const
Vector3DBase unit() const
Definition: Vector3DBase.h:54
FreeTrajectoryState innerFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
bool hasZed() const
Does it have the Z projection?
virtual LocalPoint localPosition() const =0
virtual float width() const =0
FreeTrajectoryState outerFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
FreeTrajectoryState initialFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
void fillHO(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
float xx() const
Definition: LocalError.h:22
def move(src, dest)
Definition: eostools.py:511
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
std::vector< std::string > set_intersection(std::vector< std::string > const &v1, std::vector< std::string > const &v2)
const Bounds & bounds() const
Definition: Surface.h:87