CMS 3D CMS Logo

SimHitMatcher.cc
Go to the documentation of this file.
7 #include <algorithm>
8 #include <iomanip>
10 
11 using namespace std;
12 
13 namespace {
14 
15 bool is_gem(unsigned int detid)
16 {
17  DetId id(detid);
18  if (id.subdetId() == MuonSubdetId::GEM) return true;
19  return false;
20 }
21 
22 }
23 
24 
25 SimHitMatcher::SimHitMatcher(const SimTrack& track, const edm::Event& e, const GEMGeometry& geom, const edm::ParameterSet& cfg, edm::EDGetToken& simhitToken, edm::EDGetToken& simtrackToken, edm::EDGetToken& simvertexToken ):track_(track),gem_geo_(geom)
26 {
27  simMuOnlyGEM_ = cfg.getUntrackedParameter<bool>("simMuOnlyGEM", true);
28  discardEleHitsGEM_ = cfg.getUntrackedParameter<bool>("discardEleHitsGEM", true);
29  simInputLabel_ = cfg.getUntrackedParameter<std::string>("simInputLabel");
30  verbose_ = false;
31 
32  e.getByToken(simtrackToken, sim_tracks);
33  e.getByToken(simvertexToken, sim_vertices);
34  e.getByToken(simhitToken, gem_hits);
35  init(e);
36 }
37 
38 
40 
41 
43 {
44 
45 
46  // fill trkId2Index associoation:
47  int no = 0;
48  trkid_to_index_.clear();
49  for (auto& t: *sim_tracks.product())
50  {
51  trkid_to_index_[t.trackId()] = no;
52  no++;
53  }
54  vector<unsigned> track_ids = getIdsOfSimTrackShower(track_.trackId(), *sim_tracks.product(), *sim_vertices.product());
55 
57 
58  if (verbose_)
59  {
60  auto gem_det_ids = detIdsGEM();
61  for (auto id: gem_det_ids)
62  {
63  auto gem_simhits = hitsInDetId(id);
64  auto gem_simhits_gp = simHitsMeanPosition(gem_simhits);
65  auto strips = hitStripsInDetId(id);
66  cout<<"detid "<<GEMDetId(id)<<": "<<gem_simhits.size()<<" "<<gem_simhits_gp.phi()<<" "<< gem_detid_to_hits_[id].size()<<endl;
67  cout<<"nstrp "<<strips.size()<<endl;
68  cout<<"strps : "; std::copy(strips.begin(), strips.end(), ostream_iterator<int>(cout, " ")); cout<<endl;
69  }
70  auto gem_ch_ids = chamberIdsGEM();
71  for (auto id: gem_ch_ids)
72  {
73  auto& gem_simhits = hitsInChamber(id);
74  auto gem_simhits_gp = simHitsMeanPosition(gem_simhits);
75  cout<<"cchid "<<GEMDetId(id)<<": "<<gem_simhits.size()<<" "<<gem_simhits_gp.phi()<<" "<< gem_chamber_to_hits_[id].size()<<endl;
76  }
77  auto gem_sch_ids = superChamberIdsGEM();
78  for (auto id: gem_sch_ids)
79  {
80  auto& gem_simhits = hitsInSuperChamber(id);
81  auto gem_simhits_gp = simHitsMeanPosition(gem_simhits);
82  cout<<"schid "<<GEMDetId(id)<<": "<<nCoincidencePadsWithHits() <<" | "<<gem_simhits.size()<<" "<<gem_simhits_gp.phi()<<" "<< gem_superchamber_to_hits_[id].size()<<endl;
83  }
84  }
85 }
86 
87 
88 std::vector<unsigned int>
89 SimHitMatcher::getIdsOfSimTrackShower(unsigned int initial_trk_id,
91 {
92  vector<unsigned int> result;
93  result.push_back(initial_trk_id);
94 
95  if (! (simMuOnlyGEM_ ) ) return result;
96  for (auto& t: sim_tracks)
97  {
98  SimTrack last_trk = t;
99  bool is_child = 0;
100  while (1)
101  {
102  if ( last_trk.noVertex() ) break;
103  if ( sim_vertices[last_trk.vertIndex()].noParent() ) break;
104 
105  unsigned parentId = sim_vertices[last_trk.vertIndex()].parentIndex();
106  if ( parentId == initial_trk_id )
107  {
108  is_child = 1;
109  break;
110  }
111 
112  auto association = trkid_to_index_.find( parentId );
113  if ( association == trkid_to_index_.end() ) break;
114 
115  last_trk = sim_tracks[ association->second ];
116  }
117  if (is_child)
118  {
119  result.push_back(t.trackId());
120  }
121  }
122  return result;
123 }
124 
125 
126 void
127 SimHitMatcher::matchSimHitsToSimTrack(std::vector<unsigned int> track_ids,
129 {
130  for (auto& track_id: track_ids)
131  {
132  for (auto& h: gem_hits)
133  {
134  if (h.trackId() != track_id) continue;
135  int pdgid = h.particleType();
136  if (simMuOnlyGEM_ && std::abs(pdgid) != 13) continue;
137  if (discardEleHitsGEM_ && std::abs(pdgid) == 11) continue;
138 
139  gem_detid_to_hits_[ h.detUnitId() ].push_back(h);
140  gem_hits_.push_back(h);
141  GEMDetId p_id( h.detUnitId() );
142  gem_chamber_to_hits_[ p_id.chamberId().rawId() ].push_back(h);
143  GEMDetId superch_id(p_id.region(), p_id.ring(), p_id.station(), 1, p_id.chamber(), 0);
144  gem_superchamber_to_hits_[ superch_id() ].push_back(h);
145  }
146  }
147 
148  // find pads with hits
149  auto detids = detIdsGEM();
150  // find 2-layer coincidence pads with hits
151  for (auto d: detids)
152  {
153  GEMDetId id(d);
154  auto hits = hitsInDetId(d);
155  auto roll = gem_geo_.etaPartition(id);
156  //int max_npads = roll->npads();
157  set<int> pads;
158  for (auto& h: hits)
159  {
160  LocalPoint lp = h.entryPoint();
161  pads.insert( 1 + static_cast<int>(roll->padTopology().channel(lp)) );
162  }
163  gem_detids_to_pads_[d] = pads;
164  }
165 
166  // find 2-layer coincidence pads with hits
167  for (auto d: detids)
168  {
169  GEMDetId id1(d);
170  if (id1.layer() != 1) continue;
171  GEMDetId id2(id1.region(), id1.ring(), id1.station(), 2, id1.chamber(), id1.roll());
172  // does layer 2 has simhits?
173  if (detids.find(id2()) == detids.end()) continue;
174 
175  // find pads with hits in layer1
176  auto hits1 = hitsInDetId(d);
177  auto roll1 = gem_geo_.etaPartition(id1);
178  set<int> pads1;
179  for (auto& h: hits1)
180  {
181  LocalPoint lp = h.entryPoint();
182  pads1.insert( 1 + static_cast<int>(roll1->padTopology().channel(lp)) );
183  }
184 
185  // find pads with hits in layer2
186  auto hits2 = hitsInDetId(id2());
187  auto roll2 = gem_geo_.etaPartition(id2);
188  set<int> pads2;
189  for (auto& h: hits2)
190  {
191  LocalPoint lp = h.entryPoint();
192  pads2.insert( 1 + static_cast<int>(roll2->padTopology().channel(lp)) );
193  }
194 
195  set<int> copads;
196  std::set_intersection(pads1.begin(), pads1.end(), pads2.begin(), pads2.end(), std::inserter(copads, copads.begin()));
197  if (copads.empty()) continue;
198  gem_detids_to_copads_[d] = copads;
199  }
200 }
201 
202 
203 std::set<unsigned int> SimHitMatcher::detIdsGEM() const
204 {
205  std::set<unsigned int> result;
206  for (auto& p: gem_detid_to_hits_) result.insert(p.first);
207  return result;
208 }
209 
210 
211 std::set<unsigned int> SimHitMatcher::detIdsGEMCoincidences() const
212 {
213  std::set<unsigned int> result;
214  for (auto& p: gem_detids_to_copads_) result.insert(p.first);
215  return result;
216 }
217 
218 
219 std::set<unsigned int> SimHitMatcher::chamberIdsGEM() const
220 {
221  std::set<unsigned int> result;
222  for (auto& p: gem_chamber_to_hits_) result.insert(p.first);
223  return result;
224 }
225 
226 
227 std::set<unsigned int>
229 {
230  std::set<unsigned int> result;
231  for (auto& p: gem_superchamber_to_hits_) result.insert(p.first);
232  return result;
233 }
234 
235 
236 std::set<unsigned int>
238 {
239  std::set<unsigned int> result;
240  for (auto& p: gem_detids_to_copads_)
241  {
242  GEMDetId id(p.first);
243  result.insert(id.chamberId().rawId());
244  }
245  return result;
246 }
247 
248 
250 SimHitMatcher::hitsInDetId(unsigned int detid) const
251 {
252  if (is_gem(detid))
253  {
254  if (gem_detid_to_hits_.find(detid) == gem_detid_to_hits_.end()) return no_hits_;
255  return gem_detid_to_hits_.at(detid);
256  }
257  return no_hits_;
258 }
259 
260 
262 SimHitMatcher::hitsInChamber(unsigned int detid) const
263 {
264  if (is_gem(detid)) // make sure we use chamber id
265  {
266  GEMDetId id(detid);
267  if (gem_chamber_to_hits_.find(id.chamberId().rawId()) == gem_chamber_to_hits_.end()) return no_hits_;
268  return gem_chamber_to_hits_.at(id.chamberId().rawId());
269  }
270  return no_hits_;
271 }
272 
273 
275 SimHitMatcher::hitsInSuperChamber(unsigned int detid) const
276 {
277  if (is_gem(detid))
278  {
279  GEMDetId id(detid);
280  if (gem_superchamber_to_hits_.find(id.chamberId().rawId()) == gem_superchamber_to_hits_.end()) return no_hits_;
281  return gem_superchamber_to_hits_.at(id.chamberId().rawId());
282  }
283  return no_hits_;
284 }
285 
286 
287 int
289 {
290  set<int> layers_with_hits;
291  auto hits = hitsInSuperChamber(detid);
292  for (auto& h: hits)
293  {
294  if (is_gem(detid))
295  {
296  GEMDetId idd(h.detUnitId());
297  layers_with_hits.insert(idd.layer());
298  }
299  }
300  return layers_with_hits.size();
301 }
302 
303 
306 {
307  if (sim_hits.empty()) return GlobalPoint(); // point "zero"
308 
309  float sumx, sumy, sumz;
310  sumx = sumy = sumz = 0.f;
311  size_t n = 0;
312  for (auto& h: sim_hits)
313  {
314  LocalPoint lp = h.entryPoint();
315  GlobalPoint gp;
316  if ( is_gem(h.detUnitId()) )
317  {
318  gp = gem_geo_.idToDet(h.detUnitId())->surface().toGlobal(lp);
319  }
320  else continue;
321  sumx += gp.x();
322  sumy += gp.y();
323  sumz += gp.z();
324  ++n;
325  }
326  if (n == 0) return GlobalPoint();
327  return GlobalPoint(sumx/n, sumy/n, sumz/n);
328 }
329 
330 
332 {
333  if (sim_hits.empty()) return -1.f;
334 
335  float sums = 0.f;
336  size_t n = 0;
337  for (auto& h: sim_hits)
338  {
339  LocalPoint lp = h.entryPoint();
340  float s;
341  auto d = h.detUnitId();
342  if ( is_gem(d) )
343  {
344  s = gem_geo_.etaPartition(d)->strip(lp);
345  }
346  else continue;
347  sums += s;
348  ++n;
349  }
350  if (n == 0) return -1.f;
351  return sums/n;
352 }
353 
354 
355 std::set<int> SimHitMatcher::hitStripsInDetId(unsigned int detid, int margin_n_strips) const
356 {
357  set<int> result;
358  auto simhits = hitsInDetId(detid);
359  if ( is_gem(detid) )
360  {
361  GEMDetId id(detid);
362  int max_nstrips = gem_geo_.etaPartition(id)->nstrips();
363  for (auto& h: simhits)
364  {
365  LocalPoint lp = h.entryPoint();
366  int central_strip = 1 + static_cast<int>(gem_geo_.etaPartition(id)->topology().channel(lp));
367  int smin = central_strip - margin_n_strips;
368  smin = (smin > 0) ? smin : 1;
369  int smax = central_strip + margin_n_strips;
370  smax = (smax <= max_nstrips) ? smax : max_nstrips;
371  for (int ss = smin; ss <= smax; ++ss) result.insert(ss);
372  }
373  }
374  return result;
375 }
376 
377 std::set<int> SimHitMatcher::hitPadsInDetId(unsigned int detid) const
378 {
379  set<int> none;
380  if (gem_detids_to_pads_.find(detid) == gem_detids_to_pads_.end()) return none;
381  return gem_detids_to_pads_.at(detid);
382 }
383 
384 std::set<int>
385 SimHitMatcher::hitCoPadsInDetId(unsigned int detid) const
386 {
387  set<int> none;
388  if (gem_detids_to_copads_.find(detid) == gem_detids_to_copads_.end()) return none;
389  return gem_detids_to_copads_.at(detid);
390 }
391 
392 
393 std::set<int> SimHitMatcher::hitPartitions() const
394 {
395  std::set<int> result;
396 
397  auto detids = detIdsGEM();
398  for (auto id: detids)
399  {
400  GEMDetId idd(id);
401  result.insert( idd.roll() );
402  }
403  return result;
404 }
405 
406 
407 int
409 {
410  int result = 0;
411  auto pad_ids = detIdsGEM();
412  for (auto id: pad_ids)
413  {
414  result += hitPadsInDetId(id).size();
415  }
416  return result;
417 }
418 
419 int
421 {
422  int result = 0;
423  auto copad_ids = detIdsGEMCoincidences();
424  for (auto id: copad_ids)
425  {
426  result += hitCoPadsInDetId(id).size();
427  }
428  return result;
429 }
std::set< unsigned int > detIdsGEM() const
GEM partitions&#39; detIds with SimHits.
T getUntrackedParameter(std::string const &, T const &) const
SimHitMatcher(const SimTrack &track, const edm::Event &, const GEMGeometry &geom, const edm::ParameterSet &cfg, edm::EDGetToken &simhitToken, edm::EDGetToken &simtrackToken, edm::EDGetToken &simvertexToken)
const edm::PSimHitContainer & hitsInDetId(unsigned int) const
simhits from a particular partition (GEM)/layer (CSC), chamber or superchamber
float simHitsMeanStrip(const edm::PSimHitContainer &sim_hits) const
calculate average strip (strip for GEM, half-strip for CSC) number for a provided collection of simhi...
int nPadsWithHits() const
How many pads with simhits in GEM did this simtrack get?
edm::Handle< edm::SimTrackContainer > sim_tracks
Definition: SimHitMatcher.h:99
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
const edm::PSimHitContainer & hitsInChamber(unsigned int) const
std::set< unsigned int > chamberIdsGEM() const
GEM chamber detIds with SimHits.
std::map< unsigned int, edm::PSimHitContainer > gem_chamber_to_hits_
std::vector< unsigned int > getIdsOfSimTrackShower(unsigned trk_id, const edm::SimTrackContainer &simTracks, const edm::SimVertexContainer &simVertices)
std::set< int > hitPartitions() const
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
std::set< int > hitStripsInDetId(unsigned int, int margin_n_strips=0) const
const SimTrack & track_
Definition: SimHitMatcher.h:87
static const int GEM
Definition: MuonSubdetId.h:15
edm::PSimHitContainer gem_hits_
int roll() const
Definition: GEMDetId.h:80
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:63
int ring() const
Definition: GEMDetId.h:59
const GEMGeometry & gem_geo_
bool discardEleHitsGEM_
Definition: SimHitMatcher.h:94
int chamber() const
Chamber id: it identifies a chamber in a ring it goes from 1 to 36.
Definition: GEMDetId.h:74
const Topology & topology() const
const GEMEtaPartition * etaPartition(GEMDetId id) const
Return a GEMEtaPartition given its id.
Definition: GEMGeometry.cc:99
GlobalPoint simHitsMeanPosition(const edm::PSimHitContainer &sim_hits) const
calculate Global average position for a provided collection of simhits
int nCoincidencePadsWithHits() const
How many coincidence pads with simhits in GEM did this simtrack get?
int nstrips() const
number of readout strips in partition
std::set< int > hitPadsInDetId(unsigned int) const
T z() const
Definition: PV3DBase.h:64
int layer() const
Layer id: each station have two layers of chambers: layer 1 is the inner chamber and layer 2 is the o...
Definition: GEMDetId.h:69
std::set< unsigned int > superChamberIdsGEMCoincidences() const
GEM superchamber detIds with SimHits 2 layers of coincidence pads.
int station() const
Station id : the station is the pair of chambers at same disk.
Definition: GEMDetId.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::PSimHitContainer no_hits_
std::map< unsigned int, edm::PSimHitContainer > gem_detid_to_hits_
bool noVertex() const
Definition: SimTrack.h:30
double f[11][100]
virtual int channel(const LocalPoint &p) const =0
std::set< unsigned int > detIdsGEMCoincidences() const
int region() const
Region id: 0 for Barrel Not in use, +/-1 For +/- Endcap.
Definition: GEMDetId.h:53
edm::Handle< edm::SimVertexContainer > sim_vertices
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:29
Definition: DetId.h:18
std::string simInputLabel_
Definition: SimHitMatcher.h:96
unsigned int trackId() const
Definition: CoreSimTrack.h:34
T const * product() const
Definition: Handle.h:81
virtual const GeomDet * idToDet(DetId) const override
Definition: GEMGeometry.cc:38
std::map< unsigned int, edm::PSimHitContainer > gem_superchamber_to_hits_
void matchSimHitsToSimTrack(std::vector< unsigned int > track_ids, const edm::PSimHitContainer &gem_hits)
float strip(const LocalPoint &lp) const
edm::Handle< edm::PSimHitContainer > gem_hits
Definition: SimHitMatcher.h:98
std::vector< SimVertex > SimVertexContainer
void init(const edm::Event &)
const edm::PSimHitContainer & hitsInSuperChamber(unsigned int) const
std::set< unsigned int > superChamberIdsGEM() const
GEM superchamber detIds with SimHits.
std::vector< PSimHit > PSimHitContainer
std::map< unsigned int, unsigned int > trkid_to_index_
T x() const
Definition: PV3DBase.h:62
std::vector< SimTrack > SimTrackContainer
std::set< int > hitCoPadsInDetId(unsigned int) const
std::map< unsigned int, std::set< int > > gem_detids_to_copads_
std::map< unsigned int, std::set< int > > gem_detids_to_pads_
int nLayersWithHitsInSuperChamber(unsigned int) const