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  DetId id(detid);
17  if (id.subdetId() == MuonSubdetId::GEM)
18  return true;
19  return false;
20  }
21 
22 } // namespace
23 
25  const edm::Event& e,
26  const GEMGeometry& geom,
27  const edm::ParameterSet& cfg,
28  edm::EDGetToken& simhitToken,
29  edm::EDGetToken& simtrackToken,
30  edm::EDGetToken& simvertexToken)
31  : track_(track), gem_geo_(geom) {
32  simMuOnlyGEM_ = cfg.getUntrackedParameter<bool>("simMuOnlyGEM", true);
33  discardEleHitsGEM_ = cfg.getUntrackedParameter<bool>("discardEleHitsGEM", true);
34  simInputLabel_ = cfg.getUntrackedParameter<std::string>("simInputLabel");
35  verbose_ = false;
36 
37  e.getByToken(simtrackToken, sim_tracks);
38  e.getByToken(simvertexToken, sim_vertices);
39  e.getByToken(simhitToken, gem_hits);
40  init(e);
41 }
42 
44 
46  // fill trkId2Index associoation:
47  int no = 0;
48  trkid_to_index_.clear();
49  for (auto& t : *sim_tracks.product()) {
50  trkid_to_index_[t.trackId()] = no;
51  no++;
52  }
53  vector<unsigned> track_ids = getIdsOfSimTrackShower(track_.trackId(), *sim_tracks.product(), *sim_vertices.product());
54 
56 
57  if (verbose_) {
58  auto gem_det_ids = detIdsGEM();
59  for (auto id : gem_det_ids) {
60  auto gem_simhits = hitsInDetId(id);
61  auto gem_simhits_gp = simHitsMeanPosition(gem_simhits);
62  auto strips = hitStripsInDetId(id);
63  cout << "detid " << GEMDetId(id) << ": " << gem_simhits.size() << " " << gem_simhits_gp.phi() << " "
64  << gem_detid_to_hits_[id].size() << endl;
65  cout << "nstrp " << strips.size() << endl;
66  cout << "strps : ";
67  std::copy(strips.begin(), strips.end(), ostream_iterator<int>(cout, " "));
68  cout << endl;
69  }
70  auto gem_ch_ids = chamberIdsGEM();
71  for (auto id : gem_ch_ids) {
72  auto& gem_simhits = hitsInChamber(id);
73  auto gem_simhits_gp = simHitsMeanPosition(gem_simhits);
74  cout << "cchid " << GEMDetId(id) << ": " << gem_simhits.size() << " " << gem_simhits_gp.phi() << " "
75  << gem_chamber_to_hits_[id].size() << endl;
76  }
77  auto gem_sch_ids = superChamberIdsGEM();
78  for (auto id : gem_sch_ids) {
79  auto& gem_simhits = hitsInSuperChamber(id);
80  auto gem_simhits_gp = simHitsMeanPosition(gem_simhits);
81  cout << "schid " << GEMDetId(id) << ": " << nCoincidencePadsWithHits() << " | " << gem_simhits.size() << " "
82  << gem_simhits_gp.phi() << " " << gem_superchamber_to_hits_[id].size() << endl;
83  }
84  }
85 }
86 
87 std::vector<unsigned int> SimHitMatcher::getIdsOfSimTrackShower(unsigned int initial_trk_id,
90  vector<unsigned int> result;
91  result.push_back(initial_trk_id);
92 
93  if (!(simMuOnlyGEM_))
94  return result;
95  for (auto& t : sim_tracks) {
96  SimTrack last_trk = t;
97  bool is_child = false;
98  while (true) {
99  if (last_trk.noVertex())
100  break;
101  if (sim_vertices[last_trk.vertIndex()].noParent())
102  break;
103 
104  unsigned parentId = sim_vertices[last_trk.vertIndex()].parentIndex();
105  if (parentId == initial_trk_id) {
106  is_child = true;
107  break;
108  }
109 
110  auto association = trkid_to_index_.find(parentId);
111  if (association == trkid_to_index_.end())
112  break;
113 
114  last_trk = sim_tracks[association->second];
115  }
116  if (is_child) {
117  result.push_back(t.trackId());
118  }
119  }
120  return result;
121 }
122 
123 void SimHitMatcher::matchSimHitsToSimTrack(std::vector<unsigned int> track_ids, const edm::PSimHitContainer& gem_hits) {
124  for (auto& track_id : track_ids) {
125  for (auto& h : gem_hits) {
126  if (h.trackId() != track_id)
127  continue;
128  int pdgid = h.particleType();
129  if (simMuOnlyGEM_ && std::abs(pdgid) != 13)
130  continue;
131  if (discardEleHitsGEM_ && std::abs(pdgid) == 11)
132  continue;
133 
134  gem_detid_to_hits_[h.detUnitId()].push_back(h);
135  gem_hits_.push_back(h);
136  GEMDetId p_id(h.detUnitId());
137  gem_chamber_to_hits_[p_id.chamberId().rawId()].push_back(h);
138  GEMDetId superch_id(p_id.region(), p_id.ring(), p_id.station(), 1, p_id.chamber(), 0);
139  gem_superchamber_to_hits_[superch_id()].push_back(h);
140  }
141  }
142 
143  // find pads with hits
144  auto detids = detIdsGEM();
145  // find 2-layer coincidence pads with hits
146  for (auto d : detids) {
147  GEMDetId id(d);
148  auto hits = hitsInDetId(d);
149  auto roll = gem_geo_.etaPartition(id);
150  //int max_npads = roll->npads();
151  set<int> pads;
152  for (auto& h : hits) {
153  LocalPoint lp = h.entryPoint();
154  pads.insert(1 + static_cast<int>(roll->padTopology().channel(lp)));
155  }
156  gem_detids_to_pads_[d] = pads;
157  }
158 
159  // find 2-layer coincidence pads with hits
160  for (auto d : detids) {
161  GEMDetId id1(d);
162  if (id1.layer() != 1)
163  continue;
164  GEMDetId id2(id1.region(), id1.ring(), id1.station(), 2, id1.chamber(), id1.roll());
165  // does layer 2 has simhits?
166  if (detids.find(id2()) == detids.end())
167  continue;
168 
169  // find pads with hits in layer1
170  auto hits1 = hitsInDetId(d);
171  auto roll1 = gem_geo_.etaPartition(id1);
172  set<int> pads1;
173  for (auto& h : hits1) {
174  LocalPoint lp = h.entryPoint();
175  pads1.insert(1 + static_cast<int>(roll1->padTopology().channel(lp)));
176  }
177 
178  // find pads with hits in layer2
179  auto hits2 = hitsInDetId(id2());
180  auto roll2 = gem_geo_.etaPartition(id2);
181  set<int> pads2;
182  for (auto& h : hits2) {
183  LocalPoint lp = h.entryPoint();
184  pads2.insert(1 + static_cast<int>(roll2->padTopology().channel(lp)));
185  }
186 
187  set<int> copads;
188  std::set_intersection(
189  pads1.begin(), pads1.end(), pads2.begin(), pads2.end(), std::inserter(copads, copads.begin()));
190  if (copads.empty())
191  continue;
192  gem_detids_to_copads_[d] = copads;
193  }
194 }
195 
196 std::set<unsigned int> SimHitMatcher::detIdsGEM() const {
197  std::set<unsigned int> result;
198  for (auto& p : gem_detid_to_hits_)
199  result.insert(p.first);
200  return result;
201 }
202 
203 std::set<unsigned int> SimHitMatcher::detIdsGEMCoincidences() const {
204  std::set<unsigned int> result;
205  for (auto& p : gem_detids_to_copads_)
206  result.insert(p.first);
207  return result;
208 }
209 
210 std::set<unsigned int> SimHitMatcher::chamberIdsGEM() const {
211  std::set<unsigned int> result;
212  for (auto& p : gem_chamber_to_hits_)
213  result.insert(p.first);
214  return result;
215 }
216 
217 std::set<unsigned int> SimHitMatcher::superChamberIdsGEM() const {
218  std::set<unsigned int> result;
219  for (auto& p : gem_superchamber_to_hits_)
220  result.insert(p.first);
221  return result;
222 }
223 
224 std::set<unsigned int> SimHitMatcher::superChamberIdsGEMCoincidences() const {
225  std::set<unsigned int> result;
226  for (auto& p : gem_detids_to_copads_) {
227  GEMDetId id(p.first);
228  result.insert(id.chamberId().rawId());
229  }
230  return result;
231 }
232 
233 const edm::PSimHitContainer& SimHitMatcher::hitsInDetId(unsigned int detid) const {
234  if (is_gem(detid)) {
235  if (gem_detid_to_hits_.find(detid) == gem_detid_to_hits_.end())
236  return no_hits_;
237  return gem_detid_to_hits_.at(detid);
238  }
239  return no_hits_;
240 }
241 
242 const edm::PSimHitContainer& SimHitMatcher::hitsInChamber(unsigned int detid) const {
243  if (is_gem(detid)) // make sure we use chamber id
244  {
245  GEMDetId id(detid);
246  if (gem_chamber_to_hits_.find(id.chamberId().rawId()) == gem_chamber_to_hits_.end())
247  return no_hits_;
248  return gem_chamber_to_hits_.at(id.chamberId().rawId());
249  }
250  return no_hits_;
251 }
252 
254  if (is_gem(detid)) {
255  GEMDetId id(detid);
256  if (gem_superchamber_to_hits_.find(id.chamberId().rawId()) == gem_superchamber_to_hits_.end())
257  return no_hits_;
258  return gem_superchamber_to_hits_.at(id.chamberId().rawId());
259  }
260  return no_hits_;
261 }
262 
263 int SimHitMatcher::nLayersWithHitsInSuperChamber(unsigned int detid) const {
264  set<int> layers_with_hits;
265  auto hits = hitsInSuperChamber(detid);
266  for (auto& h : hits) {
267  if (is_gem(detid)) {
268  GEMDetId idd(h.detUnitId());
269  layers_with_hits.insert(idd.layer());
270  }
271  }
272  return layers_with_hits.size();
273 }
274 
276  if (sim_hits.empty())
277  return GlobalPoint(); // point "zero"
278 
279  float sumx, sumy, sumz;
280  sumx = sumy = sumz = 0.f;
281  size_t n = 0;
282  for (auto& h : sim_hits) {
283  LocalPoint lp = h.entryPoint();
284  GlobalPoint gp;
285  if (is_gem(h.detUnitId())) {
286  gp = gem_geo_.idToDet(h.detUnitId())->surface().toGlobal(lp);
287  } else
288  continue;
289  sumx += gp.x();
290  sumy += gp.y();
291  sumz += gp.z();
292  ++n;
293  }
294  if (n == 0)
295  return GlobalPoint();
296  return GlobalPoint(sumx / n, sumy / n, sumz / n);
297 }
298 
300  if (sim_hits.empty())
301  return -1.f;
302 
303  float sums = 0.f;
304  size_t n = 0;
305  for (auto& h : sim_hits) {
306  LocalPoint lp = h.entryPoint();
307  float s;
308  auto d = h.detUnitId();
309  if (is_gem(d)) {
310  s = gem_geo_.etaPartition(d)->strip(lp);
311  } else
312  continue;
313  sums += s;
314  ++n;
315  }
316  if (n == 0)
317  return -1.f;
318  return sums / n;
319 }
320 
321 std::set<int> SimHitMatcher::hitStripsInDetId(unsigned int detid, int margin_n_strips) const {
322  set<int> result;
323  auto simhits = hitsInDetId(detid);
324  if (is_gem(detid)) {
325  GEMDetId id(detid);
326  int max_nstrips = gem_geo_.etaPartition(id)->nstrips();
327  for (auto& h : simhits) {
328  LocalPoint lp = h.entryPoint();
329  int central_strip = 1 + static_cast<int>(gem_geo_.etaPartition(id)->topology().channel(lp));
330  int smin = central_strip - margin_n_strips;
331  smin = (smin > 0) ? smin : 1;
332  int smax = central_strip + margin_n_strips;
333  smax = (smax <= max_nstrips) ? smax : max_nstrips;
334  for (int ss = smin; ss <= smax; ++ss)
335  result.insert(ss);
336  }
337  }
338  return result;
339 }
340 
341 std::set<int> SimHitMatcher::hitPadsInDetId(unsigned int detid) const {
342  set<int> none;
343  if (gem_detids_to_pads_.find(detid) == gem_detids_to_pads_.end())
344  return none;
345  return gem_detids_to_pads_.at(detid);
346 }
347 
348 std::set<int> SimHitMatcher::hitCoPadsInDetId(unsigned int detid) const {
349  set<int> none;
350  if (gem_detids_to_copads_.find(detid) == gem_detids_to_copads_.end())
351  return none;
352  return gem_detids_to_copads_.at(detid);
353 }
354 
355 std::set<int> SimHitMatcher::hitPartitions() const {
356  std::set<int> result;
357 
358  auto detids = detIdsGEM();
359  for (auto id : detids) {
360  GEMDetId idd(id);
361  result.insert(idd.roll());
362  }
363  return result;
364 }
365 
367  int result = 0;
368  auto pad_ids = detIdsGEM();
369  for (auto id : pad_ids) {
370  result += hitPadsInDetId(id).size();
371  }
372  return result;
373 }
374 
376  int result = 0;
377  auto copad_ids = detIdsGEMCoincidences();
378  for (auto id : copad_ids) {
379  result += hitCoPadsInDetId(id).size();
380  }
381  return result;
382 }
std::set< unsigned int > detIdsGEM() const
GEM partitions&#39; detIds with SimHits.
T getUntrackedParameter(std::string const &, T const &) const
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
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...
static constexpr int GEM
Definition: MuonSubdetId.h:14
int nPadsWithHits() const
How many pads with simhits in GEM did this simtrack get?
edm::Handle< edm::SimTrackContainer > sim_tracks
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
const edm::PSimHitContainer & hitsInChamber(unsigned int) const
std::set< unsigned int > chamberIdsGEM() const
GEM chamber detIds with SimHits.
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:49
std::set< int > hitStripsInDetId(unsigned int, int margin_n_strips=0) const
const SimTrack & track_
Definition: SimHitMatcher.h:90
edm::PSimHitContainer gem_hits_
int roll() const
Definition: GEMDetId.h:188
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:60
int ring() const
Definition: GEMDetId.h:170
const GEMGeometry & gem_geo_
bool discardEleHitsGEM_
Definition: SimHitMatcher.h:98
int chamber() const
Definition: GEMDetId.h:177
const Topology & topology() const override
const GEMEtaPartition * etaPartition(GEMDetId id) const
Return a GEMEtaPartition given its id.
Definition: GEMGeometry.cc:77
std::map< unsigned int, edm::PSimHitContainer > gem_superchamber_to_hits_
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:61
int layer() const
Definition: GEMDetId.h:184
std::set< unsigned int > superChamberIdsGEMCoincidences() const
GEM superchamber detIds with SimHits 2 layers of coincidence pads.
int station() const
Definition: GEMDetId.h:173
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::PSimHitContainer no_hits_
bool noVertex() const
Definition: SimTrack.h:31
double f[11][100]
virtual int channel(const LocalPoint &p) const =0
std::set< unsigned int > detIdsGEMCoincidences() const
int region() const
Definition: GEMDetId.h:165
d
Definition: ztail.py:151
edm::Handle< edm::SimVertexContainer > sim_vertices
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:30
Definition: DetId.h:17
std::map< unsigned int, edm::PSimHitContainer > gem_chamber_to_hits_
std::string simInputLabel_
unsigned int trackId() const
Definition: CoreSimTrack.h:31
T const * product() const
Definition: Handle.h:69
const GeomDet * idToDet(DetId) const override
Definition: GEMGeometry.cc:25
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
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.
strips
#turn off noise in all subdetectors simHcalUnsuppressedDigis.doNoise = False mix.digitizers.hcal.doNoise = False simEcalUnsuppressedDigis.doNoise = False mix.digitizers.ecal.doNoise = False simEcalUnsuppressedDigis.doESNoise = False simSiPixelDigis.AddNoise = False mix.digitizers.pixel.AddNoise = False simSiStripDigis.Noise = False mix.digitizers.strip.AddNoise = False
Definition: DigiDM_cff.py:32
std::map< unsigned int, edm::PSimHitContainer > gem_detid_to_hits_
std::vector< PSimHit > PSimHitContainer
std::map< unsigned int, unsigned int > trkid_to_index_
T x() const
Definition: PV3DBase.h:59
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