CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
22 
23 // user include files
25 
32 
42 
43 // calorimeter info
50 
54 
57 
60 
62 
63 
66 
69 #include <stack>
70 #include <set>
71 
73 #include "Math/VectorUtil.h"
74 #include <algorithm>
75 
78 // #include "TrackingTools/TrackAssociator/interface/CaloDetIdAssociator.h"
79 // #include "TrackingTools/TrackAssociator/interface/EcalDetIdAssociator.h"
80 // #include "TrackingTools/TrackAssociator/interface/PreshowerDetIdAssociator.h"
81 // #include "Utilities/Timing/interface/TimerStack.h"
82 
87 
96 
98 
99 using namespace reco;
100 
102 {
103  ivProp_ = 0;
104  defProp_ = 0;
105  useDefaultPropagator_ = false;
106 }
107 
109 {
110  if (defProp_) delete defProp_;
111 }
112 
114 {
115  ivProp_ = ptr;
116  cachedTrajectory_.setPropagator(ivProp_);
117 }
118 
120 {
121  useDefaultPropagator_ = true;
122 }
123 
124 
126 {
127  // access the calorimeter geometry
128  iSetup.get<CaloGeometryRecord>().get(theCaloGeometry_);
129  if (!theCaloGeometry_.isValid())
130  throw cms::Exception("FatalError") << "Unable to find CaloGeometryRecord in event!\n";
131 
132  // get the tracking Geometry
133  iSetup.get<GlobalTrackingGeometryRecord>().get(theTrackingGeometry_);
134  if (!theTrackingGeometry_.isValid())
135  throw cms::Exception("FatalError") << "Unable to find GlobalTrackingGeometryRecord in event!\n";
136 
137  if (useDefaultPropagator_ && (! defProp_ || theMagneticFeildWatcher_.check(iSetup) ) ) {
138  // setup propagator
140  iSetup.get<IdealMagneticFieldRecord>().get(bField);
141 
143  prop->setMaterialMode(false);
144  prop->applyRadX0Correction(true);
145  // prop->setDebug(true); // tmp
146  defProp_ = prop;
147  setPropagator(defProp_);
148  }
149 
150  iSetup.get<DetIdAssociatorRecord>().get("EcalDetIdAssociator", ecalDetIdAssociator_);
151  iSetup.get<DetIdAssociatorRecord>().get("HcalDetIdAssociator", hcalDetIdAssociator_);
152  iSetup.get<DetIdAssociatorRecord>().get("HODetIdAssociator", hoDetIdAssociator_);
153  iSetup.get<DetIdAssociatorRecord>().get("CaloDetIdAssociator", caloDetIdAssociator_);
154  iSetup.get<DetIdAssociatorRecord>().get("MuonDetIdAssociator", muonDetIdAssociator_);
155  iSetup.get<DetIdAssociatorRecord>().get("PreshowerDetIdAssociator", preshowerDetIdAssociator_);
156 }
157 
159  const edm::EventSetup& iSetup,
160  const FreeTrajectoryState& fts,
162 {
163  return associate(iEvent,iSetup,parameters,&fts);
164 }
165 
167  const edm::EventSetup& iSetup,
169  const FreeTrajectoryState* innerState,
170  const FreeTrajectoryState* outerState)
171 {
173  if (! parameters.useEcal && ! parameters.useCalo && ! parameters.useHcal &&
174  ! parameters.useHO && ! parameters.useMuon && !parameters.usePreshower)
175  throw cms::Exception("ConfigurationError") <<
176  "Configuration error! No subdetector was selected for the track association.";
177  // TimerStack timers;
178  // timers.push("TrackDetectorAssociator::associate",TimerStack::DetailedMonitoring);
179 
180  SteppingHelixStateInfo trackOrigin(*innerState);
181  info.stateAtIP = *innerState;
182  cachedTrajectory_.setStateAtIP(trackOrigin);
183 
184  init( iSetup );
185  // get track trajectory
186  // timers.push("TrackDetectorAssociator::fillEcal::propagation");
187  // ECAL points (EB+EE)
188  // If the phi angle between a track entrance and exit points is more
189  // than 2 crystals, it is possible that the track will cross 3 crystals
190  // and therefore one has to check at least 3 points along the track
191  // trajectory inside ECAL. In order to have a chance to cross 4 crystalls
192  // in the barrel, a track should have P_t as low as 3 GeV or smaller
193  // If it's necessary, number of points along trajectory can be increased
194 
195  info.setCaloGeometry(theCaloGeometry_);
196 
197  // timers.push("TrackDetectorAssociator::associate::getTrajectories");
198  cachedTrajectory_.reset_trajectory();
199  // estimate propagation outer boundaries based on
200  // requested sub-detector information. For now limit
201  // propagation region only if muon matching is not
202  // requested.
203  double HOmaxR = hoDetIdAssociator_->volume().maxR();
204  double HOmaxZ = hoDetIdAssociator_->volume().maxZ();
205  double minR = ecalDetIdAssociator_->volume().minR();
206  double minZ = preshowerDetIdAssociator_->volume().minZ();
207  cachedTrajectory_.setMaxHORadius(HOmaxR);
208  cachedTrajectory_.setMaxHOLength(HOmaxZ*2.);
209  cachedTrajectory_.setMinDetectorRadius(minR);
210  cachedTrajectory_.setMinDetectorLength(minZ*2.);
211 
212  double maxR(0);
213  double maxZ(0);
214 
215  if (parameters.useMuon) {
216  maxR = muonDetIdAssociator_->volume().maxR();
217  maxZ = muonDetIdAssociator_->volume().maxZ();
218  cachedTrajectory_.setMaxDetectorRadius(maxR);
219  cachedTrajectory_.setMaxDetectorLength(maxZ*2.);
220  }
221  else {
222  maxR = HOmaxR;
223  maxZ = HOmaxZ;
224  cachedTrajectory_.setMaxDetectorRadius(HOmaxR);
225  cachedTrajectory_.setMaxDetectorLength(HOmaxZ*2.);
226  }
227 
228  // If track extras exist and outerState is before HO maximum, then use outerState
229  if (outerState) {
230  if (outerState->position().perp()<HOmaxR && fabs(outerState->position().z())<HOmaxZ) {
231  LogTrace("TrackAssociator") << "Using outerState as trackOrigin at Rho=" << outerState->position().perp()
232  << " Z=" << outerState->position().z() << "\n";
233  trackOrigin = SteppingHelixStateInfo(*outerState);
234  }
235  else if(innerState) {
236  LogTrace("TrackAssociator") << "Using innerState as trackOrigin at Rho=" << innerState->position().perp()
237  << " Z=" << innerState->position().z() << "\n";
238  trackOrigin = SteppingHelixStateInfo(*innerState);
239  }
240  }
241 
242  if ( ! cachedTrajectory_.propagateAll(trackOrigin) ) return info;
243 
244  // get trajectory in calorimeters
245  cachedTrajectory_.findEcalTrajectory( ecalDetIdAssociator_->volume() );
246  cachedTrajectory_.findHcalTrajectory( hcalDetIdAssociator_->volume() );
247  cachedTrajectory_.findHOTrajectory( hoDetIdAssociator_->volume() );
248  cachedTrajectory_.findPreshowerTrajectory( preshowerDetIdAssociator_->volume() );
249 
250  info.trkGlobPosAtEcal = getPoint( cachedTrajectory_.getStateAtEcal().position() );
251  info.trkGlobPosAtHcal = getPoint( cachedTrajectory_.getStateAtHcal().position() );
252  info.trkGlobPosAtHO = getPoint( cachedTrajectory_.getStateAtHO().position() );
253 
254  info.trkMomAtEcal = cachedTrajectory_.getStateAtEcal().momentum();
255  info.trkMomAtHcal = cachedTrajectory_.getStateAtHcal().momentum();
256  info.trkMomAtHO = cachedTrajectory_.getStateAtHO().momentum();
257 
258  // timers.pop_and_push("TrackDetectorAssociator::associate::fillInfo");
259 
260  if (parameters.useEcal) fillEcal( iEvent, info, parameters);
261  if (parameters.useCalo) fillCaloTowers( iEvent, info, parameters);
262  if (parameters.useHcal) fillHcal( iEvent, info, parameters);
263  if (parameters.useHO) fillHO( iEvent, info, parameters);
264  if (parameters.usePreshower) fillPreshower( iEvent, info, parameters);
265  if (parameters.useMuon) fillMuon( iEvent, info, parameters);
266  if (parameters.truthMatch) fillCaloTruth( iEvent, info, parameters);
267 
268  return info;
269 }
270 
274 {
275  // TimerStack timers;
276  // timers.push("TrackDetectorAssociator::fillEcal");
277 
278  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getEcalTrajectory();
279 
280  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
281  itr != trajectoryStates.end(); itr++)
282  LogTrace("TrackAssociator") << "ECAL trajectory point (rho, z, phi): " << itr->position().perp() <<
283  ", " << itr->position().z() << ", " << itr->position().phi();
284 
285  std::vector<GlobalPoint> coreTrajectory;
286  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
287  itr != trajectoryStates.end(); itr++) coreTrajectory.push_back(itr->position());
288 
289  if(coreTrajectory.empty()) {
290  LogTrace("TrackAssociator") << "ECAL track trajectory is empty; moving on\n";
291  info.isGoodEcal = 0;
292  return;
293  }
294  info.isGoodEcal = 1;
295 
296  // Find ECAL crystals
297  // timers.push("TrackDetectorAssociator::fillEcal::access::EcalBarrel");
299  iEvent.getByToken(parameters.EBRecHitsToken, EBRecHits);
300  if (!EBRecHits.isValid()) throw cms::Exception("FatalError") << "Unable to find EBRecHitCollection in the event!\n";
301 
302  // timers.pop_and_push("TrackDetectorAssociator::fillEcal::access::EcalEndcaps");
304  iEvent.getByToken(parameters.EERecHitsToken, EERecHits);
305  if (!EERecHits.isValid()) throw cms::Exception("FatalError") << "Unable to find EERecHitCollection in event!\n";
306 
307  // timers.pop_and_push("TrackDetectorAssociator::fillEcal::matching");
308  // timers.push("TrackDetectorAssociator::fillEcal::matching::region");
309  std::set<DetId> ecalIdsInRegion;
310  if (parameters.accountForTrajectoryChangeCalo){
311  // get trajectory change with respect to initial state
312  DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToEcal),
313  parameters.dREcalPreselection);
314  ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0],mapRange);
315  } else ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dREcalPreselection);
316  // timers.pop_and_push("TrackDetectorAssociator::fillEcal::matching::cone");
317  LogTrace("TrackAssociator") << "ECAL hits in the region: " << ecalIdsInRegion.size();
318  if (parameters.dREcalPreselection > parameters.dREcal)
319  ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsInACone(ecalIdsInRegion, coreTrajectory, parameters.dREcal);
320  LogTrace("TrackAssociator") << "ECAL hits in the cone: " << ecalIdsInRegion.size();
321  std::vector<DetId> crossedEcalIds =
322  ecalDetIdAssociator_->getCrossedDetIds(ecalIdsInRegion, coreTrajectory);
323  LogTrace("TrackAssociator") << "ECAL crossed hits " << crossedEcalIds.size();
324 
325  info.crossedEcalIds = crossedEcalIds;
326 
327  // add EcalRecHits
328  // timers.pop_and_push("TrackDetectorAssociator::fillEcal::addCrossedHits");
329  for(std::vector<DetId>::const_iterator itr=crossedEcalIds.begin(); itr!=crossedEcalIds.end();itr++)
330  {
331  std::vector<EcalRecHit>::const_iterator ebHit = (*EBRecHits).find(*itr);
332  std::vector<EcalRecHit>::const_iterator eeHit = (*EERecHits).find(*itr);
333  if(ebHit != (*EBRecHits).end())
334  info.crossedEcalRecHits.push_back(&*ebHit);
335  else if(eeHit != (*EERecHits).end())
336  info.crossedEcalRecHits.push_back(&*eeHit);
337  else
338  LogTrace("TrackAssociator") << "Crossed EcalRecHit is not found for DetId: " << itr->rawId();
339  }
340  // timers.pop_and_push("TrackDetectorAssociator::fillEcal::addHitsInTheRegion");
341  for(std::set<DetId>::const_iterator itr=ecalIdsInRegion.begin(); itr!=ecalIdsInRegion.end();itr++)
342  {
343  std::vector<EcalRecHit>::const_iterator ebHit = (*EBRecHits).find(*itr);
344  std::vector<EcalRecHit>::const_iterator eeHit = (*EERecHits).find(*itr);
345  if(ebHit != (*EBRecHits).end())
346  info.ecalRecHits.push_back(&*ebHit);
347  else if(eeHit != (*EERecHits).end())
348  info.ecalRecHits.push_back(&*eeHit);
349  else
350  LogTrace("TrackAssociator") << "EcalRecHit from the cone is not found for DetId: " << itr->rawId();
351  }
352 }
353 
357 {
358  // TimerStack timers;
359  // timers.push("TrackDetectorAssociator::fillCaloTowers");
360 
361  // use ECAL and HCAL trajectories to match a tower. (HO isn't used for matching).
362  std::vector<GlobalPoint> trajectory;
363  const std::vector<SteppingHelixStateInfo>& ecalTrajectoryStates = cachedTrajectory_.getEcalTrajectory();
364  const std::vector<SteppingHelixStateInfo>& hcalTrajectoryStates = cachedTrajectory_.getHcalTrajectory();
365  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = ecalTrajectoryStates.begin();
366  itr != ecalTrajectoryStates.end(); itr++) trajectory.push_back(itr->position());
367  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = hcalTrajectoryStates.begin();
368  itr != hcalTrajectoryStates.end(); itr++) trajectory.push_back(itr->position());
369 
370  if(trajectory.empty()) {
371  LogTrace("TrackAssociator") << "HCAL trajectory is empty; moving on\n";
372  info.isGoodCalo = 0;
373  return;
374  }
375  info.isGoodCalo = 1;
376 
377  // find crossed CaloTowers
378  // timers.push("TrackDetectorAssociator::fillCaloTowers::access::CaloTowers");
380  iEvent.getByToken(parameters.caloTowersToken, caloTowers);
381  if (!caloTowers.isValid()) throw cms::Exception("FatalError") << "Unable to find CaloTowers in event!\n";
382 
383  // timers.pop_and_push("TrackDetectorAssociator::fillCaloTowers::matching");
384  std::set<DetId> caloTowerIdsInRegion;
385  if (parameters.accountForTrajectoryChangeCalo){
386  // get trajectory change with respect to initial state
387  DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHcal),
388  parameters.dRHcalPreselection);
389  caloTowerIdsInRegion = caloDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0],mapRange);
390  } else caloTowerIdsInRegion = caloDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0], parameters.dRHcalPreselection);
391 
392  LogTrace("TrackAssociator") << "Towers in the region: " << caloTowerIdsInRegion.size();
393  std::set<DetId> caloTowerIdsInACone = caloDetIdAssociator_->getDetIdsInACone(caloTowerIdsInRegion, trajectory, parameters.dRHcal);
394  LogTrace("TrackAssociator") << "Towers in the cone: " << caloTowerIdsInACone.size();
395  std::vector<DetId> crossedCaloTowerIds = caloDetIdAssociator_->getCrossedDetIds(caloTowerIdsInRegion, trajectory);
396  LogTrace("TrackAssociator") << "Towers crossed: " << crossedCaloTowerIds.size();
397 
398  info.crossedTowerIds = crossedCaloTowerIds;
399 
400  // add CaloTowers
401  // timers.pop_and_push("TrackDetectorAssociator::fillCaloTowers::addCrossedTowers");
402  for(std::vector<DetId>::const_iterator itr=crossedCaloTowerIds.begin(); itr!=crossedCaloTowerIds.end();itr++)
403  {
404  CaloTowerCollection::const_iterator tower = (*caloTowers).find(*itr);
405  if(tower != (*caloTowers).end())
406  info.crossedTowers.push_back(&*tower);
407  else
408  LogTrace("TrackAssociator") << "Crossed CaloTower is not found for DetId: " << (*itr).rawId();
409  }
410 
411  // timers.pop_and_push("TrackDetectorAssociator::fillCaloTowers::addTowersInTheRegion");
412  for(std::set<DetId>::const_iterator itr=caloTowerIdsInACone.begin(); itr!=caloTowerIdsInACone.end();itr++)
413  {
414  CaloTowerCollection::const_iterator tower = (*caloTowers).find(*itr);
415  if(tower != (*caloTowers).end())
416  info.towers.push_back(&*tower);
417  else
418  LogTrace("TrackAssociator") << "CaloTower from the cone is not found for DetId: " << (*itr).rawId();
419  }
420 
421 }
422 
426 {
427  std::vector<GlobalPoint> trajectory;
428  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getPreshowerTrajectory();
429  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
430  itr != trajectoryStates.end(); itr++) trajectory.push_back(itr->position());
431 
432  if(trajectory.empty()) {
433  LogTrace("TrackAssociator") << "Preshower trajectory is empty; moving on\n";
434  return;
435  }
436 
437  std::set<DetId> idsInRegion =
438  preshowerDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0],
439  parameters.dRPreshowerPreselection);
440 
441  LogTrace("TrackAssociator") << "Number of Preshower Ids in the region: " << idsInRegion.size();
442  std::vector<DetId> crossedIds = preshowerDetIdAssociator_->getCrossedDetIds(idsInRegion, trajectory);
443  LogTrace("TrackAssociator") << "Number of Preshower Ids in crossed: " << crossedIds.size();
444  info.crossedPreshowerIds = crossedIds;
445 }
446 
447 
451 {
452  // TimerStack timers;
453  // timers.push("TrackDetectorAssociator::fillHcal");
454 
455  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getHcalTrajectory();
456 
457  std::vector<GlobalPoint> coreTrajectory;
458  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
459  itr != trajectoryStates.end(); itr++) coreTrajectory.push_back(itr->position());
460 
461  if(coreTrajectory.empty()) {
462  LogTrace("TrackAssociator") << "HCAL trajectory is empty; moving on\n";
463  info.isGoodHcal = 0;
464  return;
465  }
466  info.isGoodHcal = 1;
467 
468  // find crossed Hcals
469  // timers.push("TrackDetectorAssociator::fillHcal::access::Hcal");
471  iEvent.getByToken(parameters.HBHEcollToken, collection);
472  if ( ! collection.isValid() ) throw cms::Exception("FatalError") << "Unable to find HBHERecHits in event!\n";
473 
474  // timers.pop_and_push("TrackDetectorAssociator::fillHcal::matching");
475  std::set<DetId> idsInRegion;
476  if (parameters.accountForTrajectoryChangeCalo){
477  // get trajectory change with respect to initial state
478  DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHcal),
479  parameters.dRHcalPreselection);
480  idsInRegion = hcalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
481  } else idsInRegion = hcalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dRHcalPreselection);
482 
483  LogTrace("TrackAssociator") << "HCAL hits in the region: " << idsInRegion.size() << "\n" << DetIdInfo::info(idsInRegion);
484  std::set<DetId> idsInACone = hcalDetIdAssociator_->getDetIdsInACone(idsInRegion, coreTrajectory, parameters.dRHcal);
485  LogTrace("TrackAssociator") << "HCAL hits in the cone: " << idsInACone.size() << "\n" << DetIdInfo::info(idsInACone);
486  std::vector<DetId> crossedIds =
487  hcalDetIdAssociator_->getCrossedDetIds(idsInRegion, coreTrajectory);
488  LogTrace("TrackAssociator") << "HCAL hits crossed: " << crossedIds.size() << "\n" << DetIdInfo::info(crossedIds);
489 
490  info.crossedHcalIds = crossedIds;
491  // timers.pop_and_push("TrackDetectorAssociator::fillHcal::addCrossedHits");
492  // add Hcal
493  // timers.push("TrackDetectorAssociator::fillHcal::addHcal");
494  for(std::vector<DetId>::const_iterator itr=crossedIds.begin(); itr!=crossedIds.end();itr++)
495  {
496  HBHERecHitCollection::const_iterator hit = (*collection).find(*itr);
497  if( hit != (*collection).end() )
498  info.crossedHcalRecHits.push_back(&*hit);
499  else
500  LogTrace("TrackAssociator") << "Crossed HBHERecHit is not found for DetId: " << itr->rawId();
501  }
502  // timers.pop_and_push("TrackDetectorAssociator::fillHcal::addHitsInTheRegion");
503  for(std::set<DetId>::const_iterator itr=idsInACone.begin(); itr!=idsInACone.end();itr++)
504  {
505  HBHERecHitCollection::const_iterator hit = (*collection).find(*itr);
506  if( hit != (*collection).end() )
507  info.hcalRecHits.push_back(&*hit);
508  else
509  LogTrace("TrackAssociator") << "HBHERecHit from the cone is not found for DetId: " << itr->rawId();
510  }
511 }
512 
516 {
517  // TimerStack timers;
518  // timers.push("TrackDetectorAssociator::fillHO");
519 
520  const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getHOTrajectory();
521 
522  std::vector<GlobalPoint> coreTrajectory;
523  for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
524  itr != trajectoryStates.end(); itr++) coreTrajectory.push_back(itr->position());
525 
526  if(coreTrajectory.empty()) {
527  LogTrace("TrackAssociator") << "HO trajectory is empty; moving on\n";
528  info.isGoodHO = 0;
529  return;
530  }
531  info.isGoodHO = 1;
532 
533  // find crossed HOs
534  // timers.pop_and_push("TrackDetectorAssociator::fillHO::access::HO");
536  iEvent.getByToken(parameters.HOcollToken, collection);
537  if ( ! collection.isValid() ) throw cms::Exception("FatalError") << "Unable to find HORecHits in event!\n";
538 
539  // timers.pop_and_push("TrackDetectorAssociator::fillHO::matching");
540  std::set<DetId> idsInRegion;
541  if (parameters.accountForTrajectoryChangeCalo){
542  // get trajectory change with respect to initial state
543  DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHO),
544  parameters.dRHcalPreselection);
545  idsInRegion = hoDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
546  } else idsInRegion = hoDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dRHcalPreselection);
547 
548  LogTrace("TrackAssociator") << "idsInRegion.size(): " << idsInRegion.size();
549  std::set<DetId> idsInACone = hoDetIdAssociator_->getDetIdsInACone(idsInRegion, coreTrajectory, parameters.dRHcal);
550  LogTrace("TrackAssociator") << "idsInACone.size(): " << idsInACone.size();
551  std::vector<DetId> crossedIds =
552  hoDetIdAssociator_->getCrossedDetIds(idsInRegion, coreTrajectory);
553 
554  info.crossedHOIds = crossedIds;
555 
556  // add HO
557  // timers.pop_and_push("TrackDetectorAssociator::fillHO::addCrossedHits");
558  for(std::vector<DetId>::const_iterator itr=crossedIds.begin(); itr!=crossedIds.end();itr++)
559  {
560  HORecHitCollection::const_iterator hit = (*collection).find(*itr);
561  if( hit != (*collection).end() )
562  info.crossedHORecHits.push_back(&*hit);
563  else
564  LogTrace("TrackAssociator") << "Crossed HORecHit is not found for DetId: " << itr->rawId();
565  }
566 
567  // timers.pop_and_push("TrackDetectorAssociator::fillHO::addHitsInTheRegion");
568  for(std::set<DetId>::const_iterator itr=idsInACone.begin(); itr!=idsInACone.end();itr++)
569  {
570  HORecHitCollection::const_iterator hit = (*collection).find(*itr);
571  if( hit != (*collection).end() )
572  info.hoRecHits.push_back(&*hit);
573  else
574  LogTrace("TrackAssociator") << "HORecHit from the cone is not found for DetId: " << itr->rawId();
575  }
576 }
577 
579  const SimTrack& track,
580  const SimVertex& vertex )
581 {
582  GlobalVector vector( track.momentum().x(), track.momentum().y(), track.momentum().z() );
583  GlobalPoint point( vertex.position().x(), vertex.position().y(), vertex.position().z() );
584 
585  int charge = track.type( )> 0 ? -1 : 1; // lepton convention
586  if ( abs(track.type( )) == 211 || // pion
587  abs(track.type( )) == 321 || // kaon
588  abs(track.type( )) == 2212 )
589  charge = track.type( )< 0 ? -1 : 1;
590  return getFreeTrajectoryState(iSetup, vector, point, charge);
591 }
592 
594  const GlobalVector& momentum,
595  const GlobalPoint& vertex,
596  const int charge)
597 {
599  iSetup.get<IdealMagneticFieldRecord>().get(bField);
600 
601  GlobalTrajectoryParameters tPars(vertex, momentum, charge, &*bField);
602 
603  ROOT::Math::SMatrixIdentity id;
604  AlgebraicSymMatrix66 covT(id); covT *= 1e-6; // initialize to sigma=1e-3
605  CartesianTrajectoryError tCov(covT);
606 
607  return FreeTrajectoryState(tPars, tCov);
608 }
609 
610 
612  const reco::Track& track )
613 {
615  iSetup.get<IdealMagneticFieldRecord>().get(bField);
616 
617  GlobalVector vector( track.momentum().x(), track.momentum().y(), track.momentum().z() );
618 
619  GlobalPoint point( track.vertex().x(), track.vertex().y(), track.vertex().z() );
620 
621  GlobalTrajectoryParameters tPars(point, vector, track.charge(), &*bField);
622 
623  // FIX THIS !!!
624  // need to convert from perigee to global or helix (curvilinear) frame
625  // for now just an arbitrary matrix.
626  ROOT::Math::SMatrixIdentity id;
627  AlgebraicSymMatrix66 covT(id); covT *= 1e-6; // initialize to sigma=1e-3
628  CartesianTrajectoryError tCov(covT);
629 
630  return FreeTrajectoryState(tPars, tCov);
631 }
632 
634  const float dR )
635 {
636  DetIdAssociator::MapRange mapRange;
637  mapRange.dThetaPlus = dR;
638  mapRange.dThetaMinus = dR;
639  mapRange.dPhiPlus = dR;
640  mapRange.dPhiMinus = dR;
641  if ( delta.first > 0 )
642  mapRange.dThetaPlus += delta.first;
643  else
644  mapRange.dThetaMinus += fabs(delta.first);
645  if ( delta.second > 0 )
646  mapRange.dPhiPlus += delta.second;
647  else
648  mapRange.dPhiMinus += fabs(delta.second);
649  LogTrace("TrackAssociator") << "Selection range: (dThetaPlus, dThetaMinus, dPhiPlus, dPhiMinus, dRPreselection): " <<
650  mapRange.dThetaPlus << ", " << mapRange.dThetaMinus << ", " <<
651  mapRange.dPhiPlus << ", " << mapRange.dPhiMinus << ", " << dR;
652  return mapRange;
653 }
654 
655 void TrackDetectorAssociator::getTAMuonChamberMatches(std::vector<TAMuonChamberMatch>& matches,
657 {
658  // Strategy:
659  // Propagate through the whole detector, estimate change in eta and phi
660  // along the trajectory, add this to dRMuon and find DetIds around this
661  // direction using the map. Then propagate fast to each surface and apply
662  // final matching criteria.
663 
664  // TimerStack timers(TimerStack::Disableable);
665  // timers.push("MuonDetIdAssociator::getTrajectoryInMuonDetector");
666  // timers.push("MuonDetIdAssociator::getTrajectoryInMuonDetector::propagation",TimerStack::FastMonitoring);
667  // timers.pop();
668  // get the direction first
669  SteppingHelixStateInfo trajectoryPoint = cachedTrajectory_.getStateAtHcal();
670  // If trajectory point at HCAL is not valid, try to use the outer most state of the
671  // trajectory instead.
672  if(! trajectoryPoint.isValid() ) trajectoryPoint = cachedTrajectory_.getOuterState();
673  if(! trajectoryPoint.isValid() ) {
674  LogTrace("TrackAssociator") <<
675  "trajectory position at HCAL is not valid. Assume the track cannot reach muon detectors and skip it";
676  return;
677  }
678 
679  GlobalVector direction = trajectoryPoint.momentum().unit();
680  LogTrace("TrackAssociator") << "muon direction: " << direction << "\n\t and corresponding point: " <<
681  trajectoryPoint.position() <<"\n";
682 
683  DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::FullTrajectory),
684  parameters.dRMuonPreselection);
685 
686  // and find chamber DetIds
687 
688  // timers.push("MuonDetIdAssociator::getTrajectoryInMuonDetector::getDetIdsCloseToAPoint",TimerStack::FastMonitoring);
689  std::set<DetId> muonIdsInRegion =
690  muonDetIdAssociator_->getDetIdsCloseToAPoint(trajectoryPoint.position(), mapRange);
691  // timers.pop_and_push("MuonDetIdAssociator::getTrajectoryInMuonDetector::matching",TimerStack::FastMonitoring);
692  LogTrace("TrackAssociator") << "Number of chambers to check: " << muonIdsInRegion.size();
693  for(std::set<DetId>::const_iterator detId = muonIdsInRegion.begin(); detId != muonIdsInRegion.end(); detId++)
694  {
695  const GeomDet* geomDet = muonDetIdAssociator_->getGeomDet(*detId);
696  // timers.push("MuonDetIdAssociator::getTrajectoryInMuonDetector::matching::localPropagation",TimerStack::FastMonitoring);
697  TrajectoryStateOnSurface stateOnSurface = cachedTrajectory_.propagate( &geomDet->surface() );
698  if (! stateOnSurface.isValid()) {
699  LogTrace("TrackAssociator") << "Failed to propagate the track; moving on\n\t"<<
700  "Element is not crosssed: " << DetIdInfo::info(*detId) << "\n";
701  continue;
702  }
703  // timers.pop_and_push("MuonDetIdAssociator::getTrajectoryInMuonDetector::matching::geometryAccess",TimerStack::FastMonitoring);
704  LocalPoint localPoint = geomDet->surface().toLocal(stateOnSurface.freeState()->position());
705  LocalError localError = stateOnSurface.localError().positionError();
706  float distanceX = 0;
707  float distanceY = 0;
708  float sigmaX = 0.0;
709  float sigmaY = 0.0;
710  if(const CSCChamber* cscChamber = dynamic_cast<const CSCChamber*>(geomDet) ) {
711  const CSCChamberSpecs* chamberSpecs = cscChamber->specs();
712  if(! chamberSpecs) {
713  LogTrace("TrackAssociator") << "Failed to get CSCChamberSpecs from CSCChamber; moving on\n";
714  continue;
715  }
716  const CSCLayerGeometry* layerGeometry = chamberSpecs->oddLayerGeometry(1);
717  if(! layerGeometry) {
718  LogTrace("TrackAssociator") << "Failed to get CSCLayerGeometry from CSCChamberSpecs; moving on\n";
719  continue;
720  }
721  const CSCWireTopology* wireTopology = layerGeometry->wireTopology();
722  if(! wireTopology) {
723  LogTrace("TrackAssociator") << "Failed to get CSCWireTopology from CSCLayerGeometry; moving on\n";
724  continue;
725  }
726 
727  float wideWidth = wireTopology->wideWidthOfPlane();
728  float narrowWidth = wireTopology->narrowWidthOfPlane();
729  float length = wireTopology->lengthOfPlane();
730  // If slanted, there is no y offset between local origin and symmetry center of wire plane
731  float yOfFirstWire = fabs(wireTopology->wireAngle())>1.E-06 ? -0.5*length : wireTopology->yOfWire(1);
732  // y offset between local origin and symmetry center of wire plane
733  float yCOWPOffset = yOfFirstWire+0.5*length;
734 
735  // tangent of the incline angle from inside the trapezoid
736  float tangent = (wideWidth-narrowWidth)/(2.*length);
737  // y position wrt bottom of trapezoid
738  float yPrime = localPoint.y()+fabs(yOfFirstWire);
739  // half trapezoid width at y' is 0.5 * narrowWidth + x side of triangle with the above tangent and side y'
740  float halfWidthAtYPrime = 0.5*narrowWidth+yPrime*tangent;
741  distanceX = fabs(localPoint.x()) - halfWidthAtYPrime;
742  distanceY = fabs(localPoint.y()-yCOWPOffset) - 0.5*length;
743  sigmaX = distanceX/sqrt(localError.xx());
744  sigmaY = distanceY/sqrt(localError.yy());
745  } else {
746  distanceX = fabs(localPoint.x()) - geomDet->surface().bounds().width()/2.;
747  distanceY = fabs(localPoint.y()) - geomDet->surface().bounds().length()/2.;
748  sigmaX = distanceX/sqrt(localError.xx());
749  sigmaY = distanceY/sqrt(localError.yy());
750  }
751  // timers.pop_and_push("MuonDetIdAssociator::getTrajectoryInMuonDetector::matching::checking",TimerStack::FastMonitoring);
752  if ( (distanceX < parameters.muonMaxDistanceX && distanceY < parameters.muonMaxDistanceY) ||
753  (sigmaX < parameters.muonMaxDistanceSigmaX && sigmaY < parameters.muonMaxDistanceSigmaY) ) {
754  LogTrace("TrackAssociator") << "found a match: " << DetIdInfo::info(*detId) << "\n";
756  match.tState = stateOnSurface;
757  match.localDistanceX = distanceX;
758  match.localDistanceY = distanceY;
759  match.id = *detId;
760  matches.push_back(match);
761  } else {
762  LogTrace("TrackAssociator") << "chamber is too far: " <<
763  DetIdInfo::info(*detId) << "\n\tdistanceX: " << distanceX << "\t distanceY: " << distanceY <<
764  "\t sigmaX: " << sigmaX << "\t sigmaY: " << sigmaY << "\n";
765  }
766  //timers.pop();
767  }
768  //timers.pop();
769 
770 }
771 
775 {
776  // TimerStack timers;
777  // timers.push("TrackDetectorAssociator::fillMuon");
778 
779  // Get the segments from the event
780  // timers.push("TrackDetectorAssociator::fillMuon::access");
782  iEvent.getByToken(parameters.dtSegmentsToken, dtSegments);
783  if (! dtSegments.isValid())
784  throw cms::Exception("FatalError") << "Unable to find DTRecSegment4DCollection in event!\n";
785 
787  iEvent.getByToken(parameters.cscSegmentsToken, cscSegments);
788  if (! cscSegments.isValid())
789  throw cms::Exception("FatalError") << "Unable to find CSCSegmentCollection in event!\n";
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  // timers.pop_and_push("TrackDetectorAssociator::fillMuon::matchChembers");
802 
803  // get a set of matches corresponding to muon chambers
804  std::vector<TAMuonChamberMatch> matchedChambers;
805  LogTrace("TrackAssociator") << "Trying to Get ChamberMatches" << std::endl;
806  getTAMuonChamberMatches(matchedChambers, parameters);
807  LogTrace("TrackAssociator") << "Chambers matched: " << matchedChambers.size() << "\n";
808 
809  // Iterate over all chamber matches and fill segment matching
810  // info if it's available
811  // timers.pop_and_push("TrackDetectorAssociator::fillMuon::findSemgents");
812  for(std::vector<TAMuonChamberMatch>::iterator matchedChamber = matchedChambers.begin();
813  matchedChamber != matchedChambers.end(); matchedChamber++)
814  {
815  const GeomDet* geomDet = muonDetIdAssociator_->getGeomDet((*matchedChamber).id);
816  // DT chamber
817  if(const DTChamber* chamber = dynamic_cast<const DTChamber*>(geomDet) ) {
818  // Get the range for the corresponding segments
819  DTRecSegment4DCollection::range range = dtSegments->get(chamber->id());
820  // Loop over the segments of this chamber
821  for (DTRecSegment4DCollection::const_iterator segment = range.first; segment!=range.second; segment++) {
822  if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
823  matchedChamber->segments.back().dtSegmentRef = DTRecSegment4DRef(dtSegments, segment - dtSegments->begin());
824  }
825  }
826  }else{
827  // CSC Chamber
828  if(const CSCChamber* chamber = dynamic_cast<const CSCChamber*>(geomDet) ) {
829  // Get the range for the corresponding segments
830  CSCSegmentCollection::range range = cscSegments->get(chamber->id());
831  // Loop over the segments
832  for (CSCSegmentCollection::const_iterator segment = range.first; segment!=range.second; segment++) {
833  if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
834  matchedChamber->segments.back().cscSegmentRef = CSCSegmentRef(cscSegments, segment - cscSegments->begin());
835  }
836  }
837  }else{
838  // throw cms::Exception("FatalError") << "Failed to cast GeomDet object to either DTChamber or CSCChamber. Who is this guy anyway?\n";
839  }
840  }
841  info.chambers.push_back(*matchedChamber);
842  }
843 }
844 
845 
847  const RecSegment* segment,
849 {
850  LogTrace("TrackAssociator")
851  << "Segment local position: " << segment->localPosition() << "\n"
852  << std::hex << segment->geographicalId().rawId() << "\n";
853 
854  const GeomDet* chamber = muonDetIdAssociator_->getGeomDet(matchedChamber.id);
855  TrajectoryStateOnSurface trajectoryStateOnSurface = matchedChamber.tState;
856  GlobalPoint segmentGlobalPosition = chamber->toGlobal(segment->localPosition());
857 
858  LogTrace("TrackAssociator")
859  << "Segment global position: " << segmentGlobalPosition << " \t (R_xy,eta,phi): "
860  << segmentGlobalPosition.perp() << "," << segmentGlobalPosition.eta() << "," << segmentGlobalPosition.phi() << "\n";
861 
862  LogTrace("TrackAssociator")
863  << "\teta hit: " << segmentGlobalPosition.eta() << " \tpropagator: " << trajectoryStateOnSurface.freeState()->position().eta() << "\n"
864  << "\tphi hit: " << segmentGlobalPosition.phi() << " \tpropagator: " << trajectoryStateOnSurface.freeState()->position().phi() << std::endl;
865 
866  bool isGood = false;
867  bool isDTWithoutY = false;
868  const DTRecSegment4D* dtseg = dynamic_cast<const DTRecSegment4D*>(segment);
869  if ( dtseg && (! dtseg->hasZed()) )
870  isDTWithoutY = true;
871 
872  double deltaPhi(fabs(segmentGlobalPosition.phi()-trajectoryStateOnSurface.freeState()->position().phi()));
873  if(deltaPhi>M_PI) deltaPhi = fabs(deltaPhi-M_PI*2.);
874 
875  if( isDTWithoutY )
876  {
877  isGood = deltaPhi < parameters.dRMuon;
878  // Be in chamber
879  isGood &= fabs(segmentGlobalPosition.eta()-trajectoryStateOnSurface.freeState()->position().eta()) < .3;
880  } else isGood = sqrt( pow(segmentGlobalPosition.eta()-trajectoryStateOnSurface.freeState()->position().eta(),2) +
881  deltaPhi*deltaPhi) < parameters.dRMuon;
882 
883  if(isGood) {
884  TAMuonSegmentMatch muonSegment;
885  muonSegment.segmentGlobalPosition = getPoint(segmentGlobalPosition);
886  muonSegment.segmentLocalPosition = getPoint( segment->localPosition() );
887  muonSegment.segmentLocalDirection = getVector( segment->localDirection() );
888  muonSegment.segmentLocalErrorXX = segment->localPositionError().xx();
889  muonSegment.segmentLocalErrorYY = segment->localPositionError().yy();
890  muonSegment.segmentLocalErrorXY = segment->localPositionError().xy();
891  muonSegment.segmentLocalErrorDxDz = segment->localDirectionError().xx();
892  muonSegment.segmentLocalErrorDyDz = segment->localDirectionError().yy();
893 
894  // DANGEROUS - compiler cannot guaranty parameters ordering
895  // AlgebraicSymMatrix segmentCovMatrix = segment->parametersError();
896  // muonSegment.segmentLocalErrorXDxDz = segmentCovMatrix[2][0];
897  // muonSegment.segmentLocalErrorYDyDz = segmentCovMatrix[3][1];
898  muonSegment.segmentLocalErrorXDxDz = -999;
899  muonSegment.segmentLocalErrorYDyDz = -999;
900  muonSegment.hasZed = true;
901  muonSegment.hasPhi = true;
902 
903  // timing information
904  muonSegment.t0 = 0;
905  if ( dtseg ) {
906  if ( (dtseg->hasPhi()) && (! isDTWithoutY) ) {
907  int phiHits = dtseg->phiSegment()->specificRecHits().size();
908  // int zHits = dtseg->zSegment()->specificRecHits().size();
909  int hits=0;
910  double t0=0.;
911  // TODO: cuts on hit numbers not optimized in any way yet...
912  if (phiHits>5 && dtseg->phiSegment()->ist0Valid()) {
913  t0+=dtseg->phiSegment()->t0()*phiHits;
914  hits+=phiHits;
915  LogTrace("TrackAssociator") << " Phi t0: " << dtseg->phiSegment()->t0() << " hits: " << phiHits;
916  }
917  // the z segments seem to contain little useful information...
918 // if (zHits>3) {
919 // t0+=s->zSegment()->t0()*zHits;
920 // hits+=zHits;
921 // std::cout << " Z t0: " << s->zSegment()->t0() << " hits: " << zHits << std::endl;
922 // }
923  if (hits) muonSegment.t0 = t0/hits;
924 // std::cout << " --- t0: " << muonSegment.t0 << std::endl;
925  } else {
926  // check and set dimensionality
927  if (isDTWithoutY) muonSegment.hasZed = false;
928  if (! dtseg->hasPhi()) muonSegment.hasPhi = false;
929  }
930  }
931  matchedChamber.segments.push_back(muonSegment);
932  }
933 
934  return isGood;
935 }
936 
937 //********************** NON-CORE CODE ******************************//
938 
942 {
943  // get list of simulated tracks and their vertices
944  using namespace edm;
945  Handle<SimTrackContainer> simTracks;
946  iEvent.getByToken(parameters.simTracksToken, simTracks);
947  if (! simTracks.isValid() ) throw cms::Exception("FatalError") << "No simulated tracks found\n";
948 
949  Handle<SimVertexContainer> simVertices;
950  iEvent.getByToken(parameters.simVerticesToken, simVertices);
951  if (! simVertices.isValid() ) throw cms::Exception("FatalError") << "No simulated vertices found\n";
952 
953  // get sim calo hits
954  Handle<PCaloHitContainer> simEcalHitsEB;
955  iEvent.getByToken(parameters.simEcalHitsEBToken, simEcalHitsEB);
956  if (! simEcalHitsEB.isValid() ) throw cms::Exception("FatalError") << "No simulated ECAL EB hits found\n";
957 
958  Handle<PCaloHitContainer> simEcalHitsEE;
959  iEvent.getByToken(parameters.simEcalHitsEEToken, simEcalHitsEE);
960  if (! simEcalHitsEE.isValid() ) throw cms::Exception("FatalError") << "No simulated ECAL EE hits found\n";
961 
962  Handle<PCaloHitContainer> simHcalHits;
963  iEvent.getByToken(parameters.simHcalHitsToken, simHcalHits);
964  if (! simHcalHits.isValid() ) throw cms::Exception("FatalError") << "No simulated HCAL hits found\n";
965 
966  // find truth partner
967  SimTrackContainer::const_iterator simTrack = simTracks->begin();
968  for( ; simTrack != simTracks->end(); ++simTrack){
969  math::XYZVector simP3( simTrack->momentum().x(), simTrack->momentum().y(), simTrack->momentum().z() );
970  math::XYZVector recoP3( info.stateAtIP.momentum().x(), info.stateAtIP.momentum().y(), info.stateAtIP.momentum().z() );
971  if ( ROOT::Math::VectorUtil::DeltaR(recoP3, simP3) < 0.1 ) break;
972  }
973  if ( simTrack != simTracks->end() ) {
974  info.simTrack = &(*simTrack);
975  double ecalTrueEnergy(0);
976  double hcalTrueEnergy(0);
977 
978  // loop over calo hits
979  for( PCaloHitContainer::const_iterator hit = simEcalHitsEB->begin(); hit != simEcalHitsEB->end(); ++hit )
980  if ( hit->geantTrackId() == info.simTrack->genpartIndex() ) ecalTrueEnergy += hit->energy();
981 
982  for( PCaloHitContainer::const_iterator hit = simEcalHitsEE->begin(); hit != simEcalHitsEE->end(); ++hit )
983  if ( hit->geantTrackId() == info.simTrack->genpartIndex() ) ecalTrueEnergy += hit->energy();
984 
985  for( PCaloHitContainer::const_iterator hit = simHcalHits->begin(); hit != simHcalHits->end(); ++hit )
986  if ( hit->geantTrackId() == info.simTrack->genpartIndex() ) hcalTrueEnergy += hit->energy();
987 
988  info.ecalTrueEnergy = ecalTrueEnergy;
989  info.hcalTrueEnergy = hcalTrueEnergy;
990  info.hcalTrueEnergyCorrected = hcalTrueEnergy;
991  if ( fabs(info.trkGlobPosAtHcal.eta()) < 1.3 )
992  info.hcalTrueEnergyCorrected = hcalTrueEnergy*113.2;
993  else
994  if ( fabs(info.trkGlobPosAtHcal.eta()) < 3.0 )
995  info.hcalTrueEnergyCorrected = hcalTrueEnergy*167.2;
996  }
997 }
998 
1000  const edm::EventSetup& iSetup,
1001  const reco::Track& track,
1003  Direction direction /*= Any*/ )
1004 {
1005  double currentStepSize = cachedTrajectory_.getPropagationStep();
1006 
1008  iSetup.get<IdealMagneticFieldRecord>().get(bField);
1009 
1010  if(track.extra().isNull()) {
1011  if ( direction != InsideOut )
1012  throw cms::Exception("FatalError") <<
1013  "No TrackExtra information is available and association is done with something else than InsideOut track.\n" <<
1014  "Either change the parameter or provide needed data!\n";
1015  LogTrace("TrackAssociator") << "Track Extras not found\n";
1016  FreeTrajectoryState initialState = trajectoryStateTransform::initialFreeState(track,&*bField);
1017  return associate(iEvent, iSetup, parameters, &initialState); // 5th argument is null pointer
1018  }
1019 
1020  LogTrace("TrackAssociator") << "Track Extras found\n";
1023  FreeTrajectoryState referenceState = trajectoryStateTransform::initialFreeState(track,&*bField);
1024 
1025  LogTrace("TrackAssociator") << "inner track state (rho, z, phi):" <<
1026  track.innerPosition().Rho() << ", " << track.innerPosition().z() <<
1027  ", " << track.innerPosition().phi() << "\n";
1028  LogTrace("TrackAssociator") << "innerFreeState (rho, z, phi):" <<
1029  innerState.position().perp() << ", " << innerState.position().z() <<
1030  ", " << innerState.position().phi() << "\n";
1031 
1032  LogTrace("TrackAssociator") << "outer track state (rho, z, phi):" <<
1033  track.outerPosition().Rho() << ", " << track.outerPosition().z() <<
1034  ", " << track.outerPosition().phi() << "\n";
1035  LogTrace("TrackAssociator") << "outerFreeState (rho, z, phi):" <<
1036  outerState.position().perp() << ", " << outerState.position().z() <<
1037  ", " << outerState.position().phi() << "\n";
1038 
1039  // InsideOut first
1040  if ( crossedIP( track ) ) {
1041  switch ( direction ) {
1042  case InsideOut:
1043  case Any:
1044  return associate(iEvent, iSetup, parameters, &referenceState, &outerState);
1045  break;
1046  case OutsideIn:
1047  {
1048  cachedTrajectory_.setPropagationStep( -fabs(currentStepSize) );
1049  TrackDetMatchInfo result = associate(iEvent, iSetup, parameters, &innerState, &referenceState);
1050  cachedTrajectory_.setPropagationStep( currentStepSize );
1051  return result;
1052  break;
1053  }
1054  }
1055  } else {
1056  switch ( direction ) {
1057  case InsideOut:
1058  return associate(iEvent, iSetup, parameters, &innerState, &outerState);
1059  break;
1060  case OutsideIn:
1061  {
1062  cachedTrajectory_.setPropagationStep( -fabs(currentStepSize) );
1063  TrackDetMatchInfo result = associate(iEvent, iSetup, parameters, &outerState, &innerState);
1064  cachedTrajectory_.setPropagationStep( currentStepSize );
1065  return result;
1066  break;
1067  }
1068  case Any:
1069  {
1070  // check if we deal with clear outside-in case
1071  if ( track.innerPosition().Dot( track.innerMomentum() ) < 0 &&
1072  track.outerPosition().Dot( track.outerMomentum() ) < 0 )
1073  {
1074  cachedTrajectory_.setPropagationStep( -fabs(currentStepSize) );
1076  if ( track.innerPosition().R() < track.outerPosition().R() )
1077  result = associate(iEvent, iSetup, parameters, &innerState, &outerState);
1078  else
1079  result = associate(iEvent, iSetup, parameters, &outerState, &innerState);
1080  cachedTrajectory_.setPropagationStep( currentStepSize );
1081  return result;
1082  }
1083  }
1084  }
1085  }
1086 
1087  // all other cases
1088  return associate(iEvent, iSetup, parameters, &innerState, &outerState);
1089 }
1090 
1092  const edm::EventSetup& iSetup,
1093  const SimTrack& track,
1094  const SimVertex& vertex,
1096 {
1097  return associate(iEvent, iSetup, getFreeTrajectoryState(iSetup, track, vertex), parameters);
1098 }
1099 
1101  const edm::EventSetup& iSetup,
1102  const GlobalVector& momentum,
1103  const GlobalPoint& vertex,
1104  const int charge,
1106 {
1107  return associate(iEvent, iSetup, getFreeTrajectoryState(iSetup, momentum, vertex, charge), parameters);
1108 }
1109 
1111 {
1112  bool crossed = true;
1113  crossed &= (track.innerPosition().rho() > 3 ); // something close to active volume
1114  crossed &= (track.outerPosition().rho() > 3 ); // something close to active volume
1115  crossed &= ( ( track.innerPosition().x()*track.innerMomentum().x() +
1116  track.innerPosition().y()*track.innerMomentum().y() < 0 ) !=
1117  ( track.outerPosition().x()*track.outerMomentum().x() +
1118  track.outerPosition().y()*track.outerMomentum().y() < 0 ) );
1119  return crossed;
1120 }
dbl * delta
Definition: mlp_gen.cc:36
edm::EDGetTokenT< CaloTowerCollection > caloTowersToken
std::vector< DetId > crossedPreshowerIds
math::XYZPoint trkGlobPosAtHO
float xx() const
Definition: LocalError.h:24
dictionary parameters
Definition: Parameters.py:2
static const TGPicture * info(bool iBackgroundIsBlack)
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
const CSCWireTopology * wireTopology() const
virtual float length() const =0
T perp() const
Definition: PV3DBase.h:72
static bool crossedIP(const reco::Track &track)
const Vector & momentum() const
track momentum vector
Definition: TrackBase.h:148
std::vector< const CaloTower * > crossedTowers
virtual LocalError localDirectionError() const =0
Error on the local direction.
std::vector< const CaloTower * > towers
TrajectoryStateOnSurface tState
const TrackExtraRef & extra() const
reference to &quot;extra&quot; object
Definition: Track.h:97
std::vector< const HBHERecHit * > crossedHcalRecHits
std::vector< DetId > crossedTowerIds
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
math::XYZPoint segmentGlobalPosition
static FreeTrajectoryState getFreeTrajectoryState(const edm::EventSetup &, const reco::Track &)
get FreeTrajectoryState from different track representations
edm::Ref< CSCSegmentCollection > CSCSegmentRef
const DTChamberRecSegment2D * phiSegment() const
The superPhi segment: 0 if no phi projection available.
FreeTrajectoryState innerFreeState(const reco::Track &tk, const MagneticField *field)
std::vector< const EcalRecHit * > ecalRecHits
hits in the cone
std::vector< DetId > crossedEcalIds
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:47
math::XYZPoint segmentLocalPosition
void setCaloGeometry(edm::ESHandle< CaloGeometry > geometry)
virtual LocalVector localDirection() const =0
Local direction.
int init
Definition: HydjetWrapper.h:62
ROOT::Math::SMatrix< double, 6, 6, ROOT::Math::MatRepSym< double, 6 > > AlgebraicSymMatrix66
void useDefaultPropagator()
use the default propagator
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
std::vector< CaloTower >::const_iterator const_iterator
T y() const
Definition: PV3DBase.h:63
void fillHcal(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
const Bounds & bounds() const
Definition: Surface.h:128
bool addTAMuonSegmentMatch(TAMuonChamberMatch &, const RecSegment *, const AssociatorParameters &)
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:47
std::vector< DetId > crossedHcalIds
GlobalVector momentum() const
std::vector< const EcalRecHit * > crossedEcalRecHits
hits in detector elements crossed by a track
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
double charge(const std::vector< uint8_t > &Ampls)
math::XYZVector segmentLocalDirection
LocalError positionError() const
edm::EDGetTokenT< EBRecHitCollection > EBRecHitsToken
math::XYZPoint trkGlobPosAtHcal
FreeTrajectoryState stateAtIP
track info
void fillCaloTowers(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:42
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
void fillCaloTruth(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
edm::EDGetTokenT< edm::PCaloHitContainer > simEcalHitsEBToken
edm::EDGetTokenT< HORecHitCollection > HOcollToken
float xy() const
Definition: LocalError.h:25
float wireAngle() const
int iEvent
Definition: GenABIO.cc:230
bool isNull() const
Checks for null.
Definition: Ref.h:247
GlobalVector trkMomAtHO
void setPropagator(const Propagator *)
use a user configured propagator
void getTAMuonChamberMatches(std::vector< TAMuonChamberMatch > &matches, const AssociatorParameters &parameters)
float yy() const
Definition: LocalError.h:26
void applyRadX0Correction(bool applyRadX0Correction)
GlobalPoint position() const
T sqrt(T t)
Definition: SSEVec.h:48
LocalPoint toLocal(const GlobalPoint &gp) const
FreeTrajectoryState const * freeState(bool withErrors=true) const
T z() const
Definition: PV3DBase.h:64
std::vector< TAMuonSegmentMatch > segments
distance sign convention: negative - crossed chamber, positive - missed chamber
tuple result
Definition: query.py:137
int genpartIndex() const
index of the corresponding Generator particle in the Event container (-1 if no Genpart) ...
Definition: SimTrack.h:33
std::vector< TAMuonChamberMatch > chambers
std::vector< const HBHERecHit * > hcalRecHits
edm::EDGetTokenT< DTRecSegment4DCollection > dtSegmentsToken
std::vector< DetId > crossedHOIds
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const math::XYZTLorentzVectorD & position() const
Definition: CoreSimVertex.h:26
static std::string info(const DetId &)
Definition: DetIdInfo.cc:28
bool hasPhi() const
Does it have the Phi projection?
double lengthOfPlane() const
const LocalTrajectoryError & localError() const
edm::EDGetTokenT< edm::SimTrackContainer > simTracksToken
float yOfWire(float wire, float x=0.) const
edm::EDGetTokenT< EERecHitCollection > EERecHitsToken
bool isValid() const
Definition: HandleBase.h:76
edm::EDGetTokenT< HBHERecHitCollection > HBHEcollToken
void fillPreshower(const edm::Event &iEvent, TrackDetMatchInfo &info, const AssociatorParameters &)
GlobalVector momentum() const
#define LogTrace(id)
#define M_PI
std::vector< DTRecHit1D > specificRecHits() const
Access to specific components.
bool ist0Valid() const
double narrowWidthOfPlane() const
edm::Ref< DTRecSegment4DCollection > DTRecSegment4DRef
const Point & vertex() const
reference point on the track. This method is DEPRECATED, please use referencePoint() instead ...
Definition: TrackBase.h:154
double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:12
Vector3DBase unit() const
Definition: Vector3DBase.h:57
bool hasZed() const
Does it have the Z projection?
GlobalPoint position() const
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:49
double wideWidthOfPlane() const
GlobalVector trkMomAtEcal
edm::EDGetTokenT< edm::SimVertexContainer > simVerticesToken
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
virtual LocalError localPositionError() const =0
FreeTrajectoryState initialFreeState(const reco::Track &tk, const MagneticField *field)
const T & get() const
Definition: EventSetup.h:55
void fillMuon(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
const CSCLayerGeometry * oddLayerGeometry(int iendcap) const
Accessors for LayerGeometry&#39;s.
void init(const edm::EventSetup &)
DetIdAssociator::MapRange getMapRange(const std::pair< float, float > &delta, const float dR)
T eta() const
Definition: PV3DBase.h:76
GlobalVector trkMomAtHcal
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:25
void fillEcal(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:22
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:45
std::vector< const HORecHit * > crossedHORecHits
TrackDetMatchInfo associate(const edm::Event &, const edm::EventSetup &, const FreeTrajectoryState &, const AssociatorParameters &)
math::XYZPoint trkGlobPosAtEcal
Track position at different parts of the calorimeter.
edm::EDGetTokenT< edm::PCaloHitContainer > simHcalHitsToken
int charge() const
track electric charge
Definition: TrackBase.h:111
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6
FreeTrajectoryState outerFreeState(const reco::Track &tk, const MagneticField *field)
DetId geographicalId() const
double t0() const
Get the segment t0 (if recomputed, 0 is returned otherwise)
std::vector< const HORecHit * > hoRecHits
T x() const
Definition: PV3DBase.h:62
virtual LocalPoint localPosition() const =0
virtual float width() const =0
const SimTrack * simTrack
MC truth info.
edm::EDGetTokenT< CSCSegmentCollection > cscSegmentsToken
void fillHO(const edm::Event &, TrackDetMatchInfo &, const AssociatorParameters &)
void setMaterialMode(bool noMaterial)
Switch for material effects mode: no material effects if true.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
*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
edm::EDGetTokenT< edm::PCaloHitContainer > simEcalHitsEEToken