CMS 3D CMS Logo

EMTFSubsystemCollector.cc
Go to the documentation of this file.
2 
5 
6 #include "helper.h" // adjacent_cluster
7 
8 
9 // Specialized for CSC
10 template<>
12  CSCTag tag, // Defined in interface/EMTFSubsystemTag.h, maps to CSCCorrelatedLCTDigi
13  const edm::Event& iEvent,
14  const edm::EDGetToken& token,
16 ) const {
18  iEvent.getByToken(token, cscDigis);
19 
20  auto chamber = cscDigis->begin();
21  auto chend = cscDigis->end();
22  for( ; chamber != chend; ++chamber ) {
23  auto digi = (*chamber).second.first;
24  auto dend = (*chamber).second.second;
25  for( ; digi != dend; ++digi ) {
26  // emplace_back does the same thing as push_back: appends to the end of the vector
27  out.emplace_back((*chamber).first,*digi);
28  }
29  }
30  return;
31 }
32 
33 // Specialized for RPC
34 template<>
36  RPCTag tag, // Defined in interface/EMTFSubsystemTag.h, maps to RPCDigi
37  const edm::Event& iEvent,
38  const edm::EDGetToken& token,
40 ) const {
42  iEvent.getByToken(token, rpcDigis);
43 
44  TriggerPrimitiveCollection muon_primitives;
45 
46  auto chamber = rpcDigis->begin();
47  auto chend = rpcDigis->end();
48  for( ; chamber != chend; ++chamber ) {
49  auto digi = (*chamber).second.first;
50  auto dend = (*chamber).second.second;
51  for( ; digi != dend; ++digi ) {
52  if ((*chamber).first.region() != 0) { // 0 is barrel
53  if ((*chamber).first.station() <= 2 && (*chamber).first.ring() == 3) continue; // do not include RE1/3, RE2/3
54  if ((*chamber).first.station() >= 3 && (*chamber).first.ring() == 1) continue; // do not include RE3/1, RE4/1
55 
56  muon_primitives.emplace_back((*chamber).first,*digi);
57  }
58  }
59  }
60 
61  // Cluster the RPC digis
62  TriggerPrimitiveCollection clus_muon_primitives;
63  cluster_rpc(muon_primitives, clus_muon_primitives);
64 
65  // Output
66  std::copy(clus_muon_primitives.begin(), clus_muon_primitives.end(), std::back_inserter(out));
67  return;
68 }
69 
70 // Specialized for CPPF
71 template<>
73  emtf::CPPFTag tag, // Defined in interface/EMTFSubsystemTag.h, maps to CPPFDigi
74  const edm::Event& iEvent,
75  const edm::EDGetToken& token,
77 ) const {
79  iEvent.getByToken(token, cppfDigis);
80 
81  // Output
82  for (auto digi : *cppfDigis) {
83  out.emplace_back(digi.rpcId(), digi);
84  }
85 
86  return;
87 }
88 
89 // Specialized for GEM
90 template<>
92  GEMTag tag, // Defined in interface/EMTFSubsystemTag.h, maps to GEMPadDigi
93  const edm::Event& iEvent,
94  const edm::EDGetToken& token,
96 ) const {
98  iEvent.getByToken(token, gemDigis);
99 
100  TriggerPrimitiveCollection muon_primitives;
101 
102  auto chamber = gemDigis->begin();
103  auto chend = gemDigis->end();
104  for( ; chamber != chend; ++chamber ) {
105  auto digi = (*chamber).second.first;
106  auto dend = (*chamber).second.second;
107  for( ; digi != dend; ++digi ) {
108  muon_primitives.emplace_back((*chamber).first,*digi);
109  }
110  }
111 
112  // Cluster the GEM digis.
113  TriggerPrimitiveCollection copad_muon_primitives;
114  make_copad_gem(muon_primitives, copad_muon_primitives);
115 
116  TriggerPrimitiveCollection clus_muon_primitives;
117  cluster_gem(copad_muon_primitives, clus_muon_primitives);
118 
119  // Output
120  std::copy(clus_muon_primitives.begin(), clus_muon_primitives.end(), std::back_inserter(out));
121  return;
122 }
123 
124 
125 // _____________________________________________________________________________
126 // RPC functions
127 void EMTFSubsystemCollector::cluster_rpc(const TriggerPrimitiveCollection& muon_primitives, TriggerPrimitiveCollection& clus_muon_primitives) const {
128  // Define operator to select RPC digis
129  struct {
131  bool operator()(const value_type& x) const {
132  return (x.subsystem() == TriggerPrimitive::kRPC);
133  }
134  } rpc_digi_select;
135 
136  // Define operator to sort the RPC digis prior to clustering.
137  // Use rawId, bx and strip as the sorting id. RPC rawId fully specifies
138  // sector, subsector, endcap, station, ring, layer, roll. Strip is used as
139  // the least significant sorting id.
140  struct {
142  bool operator()(const value_type& lhs, const value_type& rhs) const {
143  bool cmp = (
144  std::make_pair(std::make_pair(lhs.rawId(), lhs.getRPCData().bx), lhs.getRPCData().strip) <
145  std::make_pair(std::make_pair(rhs.rawId(), rhs.getRPCData().bx), rhs.getRPCData().strip)
146  );
147  return cmp;
148  }
149  } rpc_digi_less;
150 
151  struct {
153  bool operator()(const value_type& lhs, const value_type& rhs) const {
154  bool cmp = (
155  std::make_pair(std::make_pair(lhs.rawId(), lhs.getRPCData().bx), lhs.getRPCData().strip) ==
156  std::make_pair(std::make_pair(rhs.rawId(), rhs.getRPCData().bx), rhs.getRPCData().strip)
157  );
158  return cmp;
159  }
160  } rpc_digi_equal;
161 
162  // Define operators for the nearest-neighbor clustering algorithm.
163  // If two digis are next to each other (check strip_hi on the 'left', and
164  // strip_low on the 'right'), cluster them (increment strip_hi on the 'left')
165  struct {
167  bool operator()(const value_type& lhs, const value_type& rhs) const {
168  bool cmp = (
169  (lhs.rawId() == rhs.rawId()) &&
170  (lhs.getRPCData().bx == rhs.getRPCData().bx) &&
171  (lhs.getRPCData().strip_hi+1 == rhs.getRPCData().strip_low)
172  );
173  return cmp;
174  }
175  } rpc_digi_adjacent;
176 
177  struct {
179  void operator()(value_type& lhs, value_type& rhs) { // pass by reference
180  lhs.accessRPCData().strip_hi += 1;
181  }
182  } rpc_digi_cluster;
183 
184  // ___________________________________________________________________________
185  // Do clustering using C++ <algorithm> functions
186 
187  // 1. Select RPC digis
188  std::copy_if(muon_primitives.begin(), muon_primitives.end(), std::back_inserter(clus_muon_primitives), rpc_digi_select);
189 
190  // 2. Sort
191  std::stable_sort(clus_muon_primitives.begin(), clus_muon_primitives.end(), rpc_digi_less);
192 
193  // 3. Remove duplicates
194  clus_muon_primitives.erase(
195  std::unique(clus_muon_primitives.begin(), clus_muon_primitives.end(), rpc_digi_equal),
196  clus_muon_primitives.end()
197  );
198 
199  // 4. Cluster adjacent digis
200  clus_muon_primitives.erase(
201  adjacent_cluster(clus_muon_primitives.begin(), clus_muon_primitives.end(), rpc_digi_adjacent, rpc_digi_cluster),
202  clus_muon_primitives.end()
203  );
204 }
205 
206 
207 // _____________________________________________________________________________
208 // GEM functions
209 void EMTFSubsystemCollector::make_copad_gem(const TriggerPrimitiveCollection& muon_primitives, TriggerPrimitiveCollection& copad_muon_primitives) const {
210  // Use the inner layer (layer 1) hit coordinates as output, and the outer
211  // layer (layer 2) as coincidence
212  // Copied from: L1Trigger/CSCTriggerPrimitives/src/GEMCoPadProcessor.cc
213 
214  const unsigned int maxDeltaBX = 1;
215  const unsigned int maxDeltaPadGE11 = 2;
216  const unsigned int maxDeltaPadGE21 = 2;
217 
218  std::map<int, TriggerPrimitiveCollection> in_pads_layer1, in_pads_layer2;
219 
220  TriggerPrimitiveCollection::const_iterator tp_it = muon_primitives.begin();
221  TriggerPrimitiveCollection::const_iterator tp_end = muon_primitives.end();
222 
223  for (; tp_it != tp_end; ++tp_it) {
224  const TriggerPrimitive& muon_primitive = *tp_it;
225 
226  // Split by layer
227  if (muon_primitive.subsystem() == TriggerPrimitive::kGEM) {
228  const GEMDetId& tp_detId = muon_primitive.detId<GEMDetId>();
229  assert(tp_detId.layer() == 1 || tp_detId.layer() == 2);
230  if (tp_detId.layer() == 1) {
231  in_pads_layer1[tp_detId.rawId()].push_back(muon_primitive);
232  } else {
233  in_pads_layer2[tp_detId.rawId()].push_back(muon_primitive);
234  }
235 
236  // Modified copad logic
237  bool modified_copad_logic = false;
238  if (modified_copad_logic) {
239  if (tp_detId.layer() == 1) {
240  auto id = tp_detId;
241  const GEMDetId co_detId(id.region(), id.ring(), id.station(), 2, id.chamber(), id.roll());
242  const GEMPadDigi co_digi(muon_primitive.getGEMData().pad, muon_primitive.getGEMData().bx);
243  const TriggerPrimitive co_muon_primitive(co_detId, co_digi);
244  in_pads_layer2[co_detId.rawId()].push_back(co_muon_primitive);
245  } else {
246  auto id = tp_detId;
247  const GEMDetId co_detId(id.region(), id.ring(), id.station(), 1, id.chamber(), id.roll());
248  const GEMPadDigi co_digi(muon_primitive.getGEMData().pad, muon_primitive.getGEMData().bx);
249  const TriggerPrimitive co_muon_primitive(co_detId, co_digi);
250  in_pads_layer1[co_detId.rawId()].push_back(co_muon_primitive);
251  }
252  }
253  }
254  }
255 
256  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_it = in_pads_layer1.begin();
257  std::map<int, TriggerPrimitiveCollection>::iterator map_tp_end = in_pads_layer1.end();
258 
259  for (; map_tp_it != map_tp_end; ++map_tp_it) {
260  const GEMDetId& id = map_tp_it->first;
261  const TriggerPrimitiveCollection& pads = map_tp_it->second;
262  assert(id.layer() == 1);
263 
264  // find the corresponding id with layer=2 and same roll number
265  const GEMDetId co_id(id.region(), id.ring(), id.station(), 2, id.chamber(), id.roll());
266 
267  // empty range = no possible coincidence pads
268  auto found = in_pads_layer2.find(co_id);
269  if (found == in_pads_layer2.end()) continue;
270 
271  // now let's correlate the pads in two layers of this partition
272  const TriggerPrimitiveCollection& co_pads = found->second;
273  for (TriggerPrimitiveCollection::const_iterator p = pads.begin(); p != pads.end(); ++p) {
274  for (TriggerPrimitiveCollection::const_iterator co_p = co_pads.begin(); co_p != co_pads.end(); ++co_p) {
275  unsigned int deltaPad = std::abs(p->getGEMData().pad - co_p->getGEMData().pad);
276  unsigned int deltaBX = std::abs(p->getGEMData().bx - co_p->getGEMData().bx);
277 
278  // check the match in pad
279  if ((id.station() == 1 && deltaPad > maxDeltaPadGE11) || (id.station() == 2 && deltaPad > maxDeltaPadGE21))
280  continue;
281 
282  // check the match in BX
283  if (deltaBX > maxDeltaBX)
284  continue;
285 
286  // make a new coincidence pad digi
287  copad_muon_primitives.push_back(*p);
288  }
289  }
290  }
291 }
292 
293 void EMTFSubsystemCollector::cluster_gem(const TriggerPrimitiveCollection& muon_primitives, TriggerPrimitiveCollection& clus_muon_primitives) const {
294  // Define operator to select GEM digis
295  struct {
297  bool operator()(const value_type& x) const {
298  return (x.subsystem() == TriggerPrimitive::kGEM);
299  }
300  } gem_digi_select;
301 
302  // Define operator to sort the GEM digis prior to clustering.
303  // Use rawId, bx and pad as the sorting id. GEM rawId fully specifies
304  // endcap, station, ring, layer, roll, chamber. Pad is used as
305  // the least significant sorting id.
306  struct {
308  bool operator()(const value_type& lhs, const value_type& rhs) const {
309  bool cmp = (
310  std::make_pair(std::make_pair(lhs.rawId(), lhs.getGEMData().bx), lhs.getGEMData().pad) <
311  std::make_pair(std::make_pair(rhs.rawId(), rhs.getGEMData().bx), rhs.getGEMData().pad)
312  );
313  return cmp;
314  }
315  } gem_digi_less;
316 
317  struct {
319  bool operator()(const value_type& lhs, const value_type& rhs) const {
320  bool cmp = (
321  std::make_pair(std::make_pair(lhs.rawId(), lhs.getGEMData().bx), lhs.getGEMData().pad) ==
322  std::make_pair(std::make_pair(rhs.rawId(), rhs.getGEMData().bx), rhs.getGEMData().pad)
323  );
324  return cmp;
325  }
326  } gem_digi_equal;
327 
328  // Define operators for the nearest-neighbor clustering algorithm.
329  // If two digis are next to each other (check pad_hi on the 'left', and
330  // pad_low on the 'right'), cluster them (increment pad_hi on the 'left')
331  struct {
333  bool operator()(const value_type& lhs, const value_type& rhs) const {
334  bool cmp = (
335  (lhs.rawId() == rhs.rawId()) &&
336  (lhs.getGEMData().bx == rhs.getGEMData().bx) &&
337  (lhs.getGEMData().pad_hi+1 == rhs.getGEMData().pad_low)
338  );
339  return cmp;
340  }
341  } gem_digi_adjacent;
342 
343  struct {
345  void operator()(value_type& lhs, value_type& rhs) { // pass by reference
346  lhs.accessGEMData().pad_hi += 1;
347  }
348  } gem_digi_cluster;
349 
350  // ___________________________________________________________________________
351  // Do clustering using C++ <algorithm> functions
352 
353  // 1. Select GEM digis
354  std::copy_if(muon_primitives.begin(), muon_primitives.end(), std::back_inserter(clus_muon_primitives), gem_digi_select);
355 
356  // 2. Sort
357  std::stable_sort(clus_muon_primitives.begin(), clus_muon_primitives.end(), gem_digi_less);
358 
359  // 3. Remove duplicates
360  clus_muon_primitives.erase(
361  std::unique(clus_muon_primitives.begin(), clus_muon_primitives.end(), gem_digi_equal),
362  clus_muon_primitives.end()
363  );
364 
365  // 4. Cluster adjacent digis
366  clus_muon_primitives.erase(
367  adjacent_cluster(clus_muon_primitives.begin(), clus_muon_primitives.end(), gem_digi_adjacent, gem_digi_cluster),
368  clus_muon_primitives.end()
369  );
370 }
void cluster_rpc(const TriggerPrimitiveCollection &muon_primitives, TriggerPrimitiveCollection &clus_muon_primitives) const
const subsystem_type subsystem() const
def copy(args, dbName)
const GEMData getGEMData() const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
void extractPrimitives(T tag, const edm::Event &iEvent, const edm::EDGetToken &token, TriggerPrimitiveCollection &out) const
int iEvent
Definition: GenABIO.cc:224
def unique(seq, keepstr=True)
Definition: tier0.py:25
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
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void make_copad_gem(const TriggerPrimitiveCollection &muon_primitives, TriggerPrimitiveCollection &copad_muon_primitives) const
L1TMuon::TriggerPrimitiveCollection TriggerPrimitiveCollection
Definition: Common.h:34
void cluster_gem(const TriggerPrimitiveCollection &muon_primitives, TriggerPrimitiveCollection &clus_muon_primitives) const