CMS 3D CMS Logo

TrackingParticleNumberOfLayers.cc
Go to the documentation of this file.
2 
4 
8 
9 namespace {
10  bool trackIdHitPairLess(const std::pair<unsigned int, const PSimHit*>& a, const std::pair<unsigned int, const PSimHit*>& b) {
11  return a.first < b.first;
12  }
13 
14  bool trackIdHitPairLessSort(const std::pair<unsigned int, const PSimHit*>& a, const std::pair<unsigned int, const PSimHit*>& b) {
15  if(a.first == b.first) {
16  const auto atof = edm::isFinite(a.second->timeOfFlight()) ? a.second->timeOfFlight() : std::numeric_limits<decltype(a.second->timeOfFlight())>::max();
17  const auto btof = edm::isFinite(b.second->timeOfFlight()) ? b.second->timeOfFlight() : std::numeric_limits<decltype(b.second->timeOfFlight())>::max();
18  return atof < btof;
19  }
20  return a.first < b.first;
21  }
22 }
23 
24 TrackingParticleNumberOfLayers::TrackingParticleNumberOfLayers(const edm::Event& iEvent, const std::vector<edm::EDGetTokenT<std::vector<PSimHit> > >& simHitTokens) {
25 
26  // A multimap linking SimTrack::trackId() to a pointer to PSimHit
27  // Similar to TrackingTruthAccumulator
28  for(const auto& simHitToken: simHitTokens) {
30  iEvent.getByToken(simHitToken, hsimhits);
31  trackIdToHitPtr_.reserve(trackIdToHitPtr_.size()+hsimhits->size());
32  for(const auto& simHit: *hsimhits) {
33  trackIdToHitPtr_.emplace_back(simHit.trackId(), &simHit);
34  }
35  }
36  std::stable_sort(trackIdToHitPtr_.begin(), trackIdToHitPtr_.end(), trackIdHitPairLessSort);
37 }
38 
39 std::tuple<std::unique_ptr<edm::ValueMap<unsigned int>>,
40  std::unique_ptr<edm::ValueMap<unsigned int>>,
41  std::unique_ptr<edm::ValueMap<unsigned int>>>
43  //Retrieve tracker topology from geometry
45  iSetup.get<TrackerTopologyRcd>().get(tTopoHandle);
46  const TrackerTopology& tTopo = *tTopoHandle;
47 
48  const TrackingParticleCollection& tps = *htps;
49  std::vector<unsigned int> valuesLayers(tps.size(), 0);
50  std::vector<unsigned int> valuesPixelLayers(tps.size(), 0);
51  std::vector<unsigned int> valuesStripMonoAndStereoLayers(tps.size(), 0);
52  for(size_t iTP=0; iTP<tps.size(); ++iTP) {
53  const TrackingParticle& tp = tps[iTP];
54  const auto pdgId = tp.pdgId();
55 
56  // I would prefer a better way...
57  constexpr unsigned int maxSubdet = static_cast<unsigned>(StripSubdetector::TEC)+1;
58  constexpr unsigned int maxLayer = 0xF+1; // as in HitPattern.h
59  bool hasHit[maxSubdet][maxLayer];
60  bool hasPixel[maxSubdet][maxLayer];
61  bool hasMono[maxSubdet][maxLayer];
62  bool hasStereo[maxSubdet][maxLayer];
63  memset(hasHit, 0, sizeof(hasHit));
64  memset(hasPixel, 0, sizeof(hasPixel));
65  memset(hasMono, 0, sizeof(hasMono));
66  memset(hasStereo, 0, sizeof(hasStereo));
67 
68  for(const SimTrack& simTrack: tp.g4Tracks()) {
69  // Logic is from TrackingTruthAccumulator
70  auto range = std::equal_range(trackIdToHitPtr_.begin(), trackIdToHitPtr_.end(), std::pair<unsigned int, const PSimHit *>(simTrack.trackId(), nullptr), trackIdHitPairLess);
71  if(range.first == range.second) continue;
72 
73  auto iHitPtr = range.first;
74  for(; iHitPtr != range.second; ++iHitPtr) {
75  // prevent simhits with particleType != pdgId from being the "first hit"
76  if(iHitPtr->second->particleType() == pdgId)
77  break;
78  }
79  if(iHitPtr == range.second) // no simhits with particleType == pdgId
80  continue;
81  int processType = iHitPtr->second->processType();
82  int particleType = iHitPtr->second->particleType();
83 
84  for(; iHitPtr != range.second; ++iHitPtr) {
85  const PSimHit& simHit = *(iHitPtr->second);
86  if(simHit.eventId() != tp.eventId())
87  continue;
88  DetId newDetector = DetId( simHit.detUnitId() );
89 
90  // Check for delta and interaction products discards
91  if( processType == simHit.processType() && particleType == simHit.particleType() && pdgId == simHit.particleType() ) {
92  // The logic of this piece follows HitPattern
93  bool isPixel = false;
94  bool isStripStereo = false;
95  bool isStripMono = false;
96 
97  switch(newDetector.subdetId()) {
100  isPixel = true;
101  break;
103  isStripMono = tTopo.tibIsRPhi(newDetector);
104  isStripStereo = tTopo.tibIsStereo(newDetector);
105  break;
107  isStripMono = tTopo.tidIsRPhi(newDetector);
108  isStripStereo = tTopo.tidIsStereo(newDetector);
109  break;
111  isStripMono = tTopo.tobIsRPhi(newDetector);
112  isStripStereo = tTopo.tobIsStereo(newDetector);
113  break;
115  isStripMono = tTopo.tecIsRPhi(newDetector);
116  isStripStereo = tTopo.tecIsStereo(newDetector);
117  break;
118  }
119 
120  const auto subdet = newDetector.subdetId();
121  const auto layer = tTopo.layer( newDetector );
122 
123  hasHit[subdet][layer] = true;
124  if(isPixel) hasPixel[subdet][layer] = isPixel;
125  else if(isStripMono) hasMono[subdet][layer] = isStripMono;
126  else if(isStripStereo) hasStereo[subdet][layer] = isStripStereo;
127  }
128  }
129  }
130 
131 
132  unsigned int nLayers = 0;
133  unsigned int nPixelLayers = 0;
134  unsigned int nStripMonoAndStereoLayers = 0;
135  for(unsigned int i=0; i<maxSubdet; ++i) {
136  for(unsigned int j=0; j<maxLayer; ++j) {
137  nLayers += hasHit[i][j];
138  nPixelLayers += hasPixel[i][j];
139  nStripMonoAndStereoLayers += (hasMono[i][j] && hasStereo[i][j]);
140  }
141  }
142 
143  valuesLayers[iTP] = nLayers;
144  valuesPixelLayers[iTP] = nPixelLayers;
145  valuesStripMonoAndStereoLayers[iTP] = nStripMonoAndStereoLayers;
146  }
147 
148  auto ret0 = std::make_unique<edm::ValueMap<unsigned int>>();
149  {
151  filler.insert(htps, valuesLayers.begin(), valuesLayers.end());
152  filler.fill();
153  }
154  auto ret1 = std::make_unique<edm::ValueMap<unsigned int>>();
155  {
157  filler.insert(htps, valuesPixelLayers.begin(), valuesPixelLayers.end());
158  filler.fill();
159  }
160  auto ret2 = std::make_unique<edm::ValueMap<unsigned int>>();
161  {
163  filler.insert(htps, valuesStripMonoAndStereoLayers.begin(), valuesStripMonoAndStereoLayers.end());
164  filler.fill();
165  }
166 
167  return std::make_tuple(std::move(ret0), std::move(ret1), std::move(ret2));
168 }
const std::vector< SimTrack > & g4Tracks() const
std::vector< TrackingParticle > TrackingParticleCollection
bool tobIsStereo(const DetId &id) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
int pdgId() const
PDG ID.
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:52
bool tobIsRPhi(const DetId &id) const
#define constexpr
bool tidIsStereo(const DetId &id) const
bool isFinite(T x)
bool tecIsStereo(const DetId &id) const
int iEvent
Definition: GenABIO.cc:230
bool tibIsRPhi(const DetId &id) const
simTrack
per collection params
EncodedEventId eventId() const
Definition: PSimHit.h:105
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
bool tecIsRPhi(const DetId &id) const
std::vector< std::pair< unsigned int, const PSimHit * > > trackIdToHitPtr_
Definition: DetId.h:18
bool tidIsRPhi(const DetId &id) const
TrackingParticleNumberOfLayers(const edm::Event &iEvent, const std::vector< edm::EDGetTokenT< std::vector< PSimHit > > > &simHitTokens)
const T & get() const
Definition: EventSetup.h:56
bool tibIsStereo(const DetId &id) const
double b
Definition: hdecay.h:120
unsigned short processType() const
Definition: PSimHit.h:118
unsigned int layer(const DetId &id) const
EncodedEventId eventId() const
Signal source, crossing number.
std::tuple< std::unique_ptr< edm::ValueMap< unsigned int > >, std::unique_ptr< edm::ValueMap< unsigned int > >, std::unique_ptr< edm::ValueMap< unsigned int > > > calculate(const edm::Handle< TrackingParticleCollection > &tps, const edm::EventSetup &iSetup) const
int particleType() const
Definition: PSimHit.h:85
double a
Definition: hdecay.h:121
bool isPixel(HitType hitType)
Monte Carlo truth information used for tracking validation.
def move(src, dest)
Definition: eostools.py:510
unsigned int detUnitId() const
Definition: PSimHit.h:93