CMS 3D CMS Logo

GEMClusterProcessor.cc
Go to the documentation of this file.
3 
4 #include <algorithm>
5 #include <iostream>
6 
8  : region_(region), station_(station), chamber_(chamber), hasGE21Geometry16Partitions_(false) {
9  isEven_ = chamber_ % 2 == 0;
10 
11  const edm::ParameterSet aux(conf.getParameter<edm::ParameterSet>("commonParam"));
12 
13  if (station_ == 1) {
14  const edm::ParameterSet tmb(conf.getParameter<edm::ParameterSet>("tmbPhase2"));
15  const edm::ParameterSet tmb_gem(conf.getParameter<edm::ParameterSet>("tmbPhase2GE11"));
16  const edm::ParameterSet copad(conf.getParameter<edm::ParameterSet>("copadParamGE11"));
17  tmbL1aWindowSize_ = tmb.getParameter<unsigned int>("tmbL1aWindowSize");
18  delayGEMinOTMB_ = tmb_gem.getParameter<unsigned int>("delayGEMinOTMB");
19  maxDeltaPad_ = copad.getParameter<unsigned int>("maxDeltaPad");
20  maxDeltaRoll_ = copad.getParameter<unsigned int>("maxDeltaRoll");
21  maxDeltaBX_ = copad.getParameter<unsigned int>("maxDeltaBX");
22  }
23 
24  if (station_ == 2) {
25  // by default set to true
27 
28  const edm::ParameterSet tmb(conf.getParameter<edm::ParameterSet>("tmbPhase2"));
29  const edm::ParameterSet tmb_gem(conf.getParameter<edm::ParameterSet>("tmbPhase2GE21"));
30  const edm::ParameterSet copad(conf.getParameter<edm::ParameterSet>("copadParamGE21"));
31  tmbL1aWindowSize_ = tmb.getParameter<unsigned int>("tmbL1aWindowSize");
32  delayGEMinOTMB_ = tmb_gem.getParameter<unsigned int>("delayGEMinOTMB");
33  maxDeltaPad_ = copad.getParameter<unsigned int>("maxDeltaPad");
34  maxDeltaRoll_ = copad.getParameter<unsigned int>("maxDeltaRoll");
35  maxDeltaBX_ = copad.getParameter<unsigned int>("maxDeltaBX");
36  }
37 }
38 
40 
42  const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
43  const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) {
44  // Step 1: clear the GEMInternalCluster vector
45  clear();
46 
47  if (in_clusters == nullptr) {
48  edm::LogWarning("GEMClusterProcessor") << "Attempt to run without valid in_clusters pointer.";
49  return;
50  }
51 
52  // Step 2: put coincidence clusters in GEMInternalCluster vector
53  addCoincidenceClusters(in_clusters);
54 
55  // Step 3: put single clusters in GEMInternalCluster vector who are not part of any coincidence cluster
56  addSingleClusters(in_clusters);
57 
58  // Step 4: translate the cluster central pad numbers into 1/8-strip number for matching with CSC trigger primitives
59  doCoordinateConversion(lookupTableME11ILT, lookupTableME21ILT);
60 }
61 
62 std::vector<GEMInternalCluster> GEMClusterProcessor::getClusters(int bx, ClusterTypes option) const {
63  std::vector<GEMInternalCluster> output;
64 
65  for (const auto& cl : clusters_) {
66  // valid single clusters with the right BX
67  if (cl.bx() == bx and cl.isValid()) {
68  // ignore the coincidence clusters
69  if (option == SingleClusters and cl.isCoincidence())
70  continue;
71  // ignore the single clusters
72  if (option == CoincidenceClusters and !cl.isCoincidence())
73  continue;
74  output.push_back(cl);
75  }
76  }
77  return output;
78 }
79 
81  // Build coincidences
82  for (auto det_range = in_clusters->begin(); det_range != in_clusters->end(); ++det_range) {
83  const GEMDetId& id = (*det_range).first;
84 
85  // coincidence pads are not built for ME0
86  if (id.isME0())
87  continue;
88 
89  // same chamber (no restriction on the roll number)
90  if (id.region() != region_ or id.station() != station_ or id.chamber() != chamber_)
91  continue;
92 
93  // all coincidences detIDs will have layer=1
94  if (id.layer() != 1)
95  continue;
96 
97  // find all corresponding ids with layer 2 and same roll that differs at most maxDeltaRoll_
98  for (unsigned int roll = id.roll() - maxDeltaRoll_; roll <= id.roll() + maxDeltaRoll_; ++roll) {
99  GEMDetId co_id(id.region(), id.ring(), id.station(), 2, id.chamber(), roll);
100 
101  auto co_clusters_range = in_clusters->get(co_id);
102 
103  // empty range = no possible coincidence pads
104  if (co_clusters_range.first == co_clusters_range.second)
105  continue;
106 
107  // now let's correlate the pads in two layers of this partition
108  const auto& pads_range = (*det_range).second;
109  for (auto p = pads_range.first; p != pads_range.second; ++p) {
110  // ignore 8-partition GE2/1 pads
111  if (id.isGE21() and p->nPartitions() == GEMPadDigiCluster::GE21) {
113  continue;
114  }
115 
116  // only consider valid pads
117  if (!p->isValid())
118  continue;
119 
120  for (auto co_p = co_clusters_range.first; co_p != co_clusters_range.second; ++co_p) {
121  // only consider valid clusters
122  if (!co_p->isValid())
123  continue;
124 
125  // check the match in BX
126  if ((unsigned)std::abs(p->bx() - co_p->bx()) > maxDeltaBX_)
127  continue;
128 
129  // get the corrected minimum and maximum of cluster 1
130  int cl1_min = p->pads().front() - maxDeltaPad_;
131  int cl1_max = p->pads().back() + maxDeltaPad_;
132 
133  // get the minimum and maximum of cluster 2
134  int cl2_min = co_p->pads().front();
135  int cl2_max = co_p->pads().back();
136 
137  // match condition
138  const bool condition1(cl1_min <= cl2_min and cl1_max >= cl2_min);
139  const bool condition2(cl1_min <= cl2_max and cl1_max >= cl2_max);
140  const bool match(condition1 or condition2);
141 
142  if (!match)
143  continue;
144 
145  auto const& p_pads = p->pads();
146  auto const& co_p_pads = co_p->pads();
147 
148  int num_unphys_pads_in_p = std::count_if(p_pads.begin(), p_pads.end(), [](auto pad) { return pad >= 192; });
149  int num_unphys_pads_co_p =
150  std::count_if(co_p_pads.begin(), co_p_pads.end(), [](auto pad) { return pad >= 192; });
151 
152  if (num_unphys_pads_in_p > 0 || num_unphys_pads_co_p > 0) {
153  edm::LogWarning("GEMClusterProcessor")
154  << "Encountered unphysical GEM pads when making a coincidence cluster, resetting cluster to empty.";
155  clusters_.emplace_back(
157  continue;
158  }
159 
160  // make a new coincidence
161  clusters_.emplace_back(id, co_id, *p, *co_p, delayGEMinOTMB_, tmbL1aWindowSize_);
162  // std::cout << clusters_.back() << std::endl;
163  }
164  }
165  }
166  }
167 }
168 
170  // first get the coincidences
171  const std::vector<GEMInternalCluster>& coincidences = clusters_;
172 
173  // now start add single clusters
174  for (auto det_range = in_clusters->begin(); det_range != in_clusters->end(); ++det_range) {
175  const GEMDetId& id = (*det_range).first;
176 
177  // ignore ME0
178  if (id.isME0())
179  continue;
180 
181  // same chamber (no restriction on the roll number)
182  if (id.region() != region_ or id.station() != station_ or id.chamber() != chamber_)
183  continue;
184 
185  const auto& clusters_range = (*det_range).second;
186  for (auto p = clusters_range.first; p != clusters_range.second; ++p) {
187  // only consider valid clusters
188  if (!p->isValid())
189  continue;
190 
191  // ignore 8-partition GE2/1 pads
192  if (id.isGE21() and p->nPartitions() == GEMPadDigiCluster::GE21) {
194  continue;
195  }
196 
197  // ignore clusters already contained in a coincidence cluster
198  if (std::find_if(std::begin(coincidences), std::end(coincidences), [p](const GEMInternalCluster& q) {
199  return q.has_cluster(*p);
200  }) != std::end(coincidences))
201  continue;
202 
203  auto const& p_pads = p->pads();
204  int num_unphys_pads = std::count_if(p_pads.begin(), p_pads.end(), [](auto pad) { return pad >= 192; });
205 
206  if (num_unphys_pads > 0) {
207  edm::LogWarning("GEMClusterProcessor")
208  << "Encountered unphysical GEM pads when making a single cluster, resetting cluster to empty.";
210  continue;
211  }
212 
213  // put the single clusters into the collection
214  if (id.layer() == 1) {
215  clusters_.emplace_back(id, id, *p, GEMPadDigiCluster(), delayGEMinOTMB_, tmbL1aWindowSize_);
216  // std::cout << clusters_.back() << std::endl;
217  } else {
218  clusters_.emplace_back(id, id, GEMPadDigiCluster(), *p, delayGEMinOTMB_, tmbL1aWindowSize_);
219  // std::cout << clusters_.back() << std::endl;
220  }
221  }
222  }
223 }
224 
226  const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) {
227  // loop on clusters
228  for (auto& cluster : clusters_) {
229  if (cluster.cl1().isValid()) {
230  // starting coordinates
231  const int layer1_first_pad = cluster.layer1_pad();
232  const int layer1_last_pad = layer1_first_pad + cluster.layer1_size() - 1;
233 
234  // calculate the 1/8-strips
235  int layer1_pad_to_first_es = -1;
236  int layer1_pad_to_last_es = -1;
237 
238  int layer1_pad_to_first_es_me1a = -1;
239  int layer1_pad_to_last_es_me1a = -1;
240 
241  // ME1/1
242  if (station_ == 1) {
243  if (isEven_) {
244  // ME1/b
245  layer1_pad_to_first_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_even(layer1_first_pad);
246  layer1_pad_to_last_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_even(layer1_last_pad);
247  // ME1/a
248  layer1_pad_to_first_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_even(layer1_first_pad);
249  layer1_pad_to_last_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_even(layer1_last_pad);
250  } else {
251  // ME1/b
252  layer1_pad_to_first_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_odd(layer1_first_pad);
253  layer1_pad_to_last_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_odd(layer1_last_pad);
254  // ME1/a
255  layer1_pad_to_first_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_odd(layer1_first_pad);
256  layer1_pad_to_last_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_odd(layer1_last_pad);
257  }
258  }
259  // ME2/1
260  if (station_ == 2) {
261  if (isEven_) {
262  layer1_pad_to_first_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_even(layer1_first_pad);
263  layer1_pad_to_last_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_even(layer1_last_pad);
264  } else {
265  layer1_pad_to_first_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_odd(layer1_first_pad);
266  layer1_pad_to_last_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_odd(layer1_last_pad);
267  }
268  }
269  // middle 1/8-strip
270  int layer1_middle_es = (layer1_pad_to_first_es + layer1_pad_to_last_es) / 2.;
271  int layer1_middle_es_me1a = (layer1_pad_to_first_es_me1a + layer1_pad_to_last_es_me1a) / 2.;
272 
273  cluster.set_layer1_first_es(layer1_pad_to_first_es);
274  cluster.set_layer1_last_es(layer1_pad_to_last_es);
275  cluster.set_layer1_middle_es(layer1_middle_es);
276 
277  if (station_ == 1) {
278  cluster.set_layer1_first_es_me1a(layer1_pad_to_first_es_me1a);
279  cluster.set_layer1_last_es_me1a(layer1_pad_to_last_es_me1a);
280  cluster.set_layer1_middle_es_me1a(layer1_middle_es_me1a);
281  }
282 
283  // calculate the wiregroups
284  // need to subtract 1 to use the LUTs
285  const int roll = cluster.roll1() - 1;
286 
287  int roll_l1_to_min_wg = -1;
288  int roll_l1_to_max_wg = -1;
289 
290  // ME1/1
291  if (station_ == 1) {
292  if (isEven_) {
293  roll_l1_to_min_wg = lookupTableME11ILT->GEM_roll_CSC_min_wg_ME11_even(roll);
294  roll_l1_to_max_wg = lookupTableME11ILT->GEM_roll_CSC_max_wg_ME11_even(roll);
295  } else {
296  roll_l1_to_min_wg = lookupTableME11ILT->GEM_roll_CSC_min_wg_ME11_odd(roll);
297  roll_l1_to_max_wg = lookupTableME11ILT->GEM_roll_CSC_max_wg_ME11_odd(roll);
298  }
299  }
300 
301  // ME2/1
302  if (station_ == 2) {
303  if (isEven_) {
304  roll_l1_to_min_wg = lookupTableME21ILT->GEM_roll_L1_CSC_min_wg_ME21_even(roll);
305  roll_l1_to_max_wg = lookupTableME21ILT->GEM_roll_L1_CSC_max_wg_ME21_even(roll);
306  } else {
307  roll_l1_to_min_wg = lookupTableME21ILT->GEM_roll_L1_CSC_min_wg_ME21_odd(roll);
308  roll_l1_to_max_wg = lookupTableME21ILT->GEM_roll_L1_CSC_max_wg_ME21_odd(roll);
309  }
310  }
311 
312  // set the values
313  cluster.set_layer1_min_wg(roll_l1_to_min_wg);
314  cluster.set_layer1_max_wg(roll_l1_to_max_wg);
315  }
316 
317  if (cluster.cl2().isValid()) {
318  // starting coordinates
319  const int layer2_first_pad = cluster.layer2_pad();
320  const int layer2_last_pad = layer2_first_pad + cluster.layer2_size() - 1;
321 
322  // calculate the 1/8-strips
323  int layer2_pad_to_first_es = -1;
324  int layer2_pad_to_last_es = -1;
325 
326  int layer2_pad_to_first_es_me1a = -1;
327  int layer2_pad_to_last_es_me1a = -1;
328 
329  if (station_ == 1) {
330  if (isEven_) {
331  // ME1/b
332  layer2_pad_to_first_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_even(layer2_first_pad);
333  layer2_pad_to_last_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_even(layer2_last_pad);
334  // ME1/a
335  layer2_pad_to_first_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_even(layer2_first_pad);
336  layer2_pad_to_last_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_even(layer2_last_pad);
337  } else {
338  // ME1/b
339  layer2_pad_to_first_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_odd(layer2_first_pad);
340  layer2_pad_to_last_es = lookupTableME11ILT->GEM_pad_CSC_es_ME11b_odd(layer2_last_pad);
341  // ME1/a
342  layer2_pad_to_first_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_odd(layer2_first_pad);
343  layer2_pad_to_last_es_me1a = lookupTableME11ILT->GEM_pad_CSC_es_ME11a_odd(layer2_last_pad);
344  }
345  }
346 
347  // ME2/1
348  if (station_ == 2) {
349  if (isEven_) {
350  layer2_pad_to_first_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_even(layer2_first_pad);
351  layer2_pad_to_last_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_even(layer2_last_pad);
352  } else {
353  layer2_pad_to_first_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_odd(layer2_first_pad);
354  layer2_pad_to_last_es = lookupTableME21ILT->GEM_pad_CSC_es_ME21_odd(layer2_last_pad);
355  }
356  }
357  // middle 1/8-strip
358  int layer2_middle_es = int((layer2_pad_to_first_es + layer2_pad_to_last_es) / 2.0);
359  int layer2_middle_es_me1a = int((layer2_pad_to_first_es_me1a + layer2_pad_to_last_es_me1a) / 2.0);
360 
361  cluster.set_layer2_first_es(layer2_pad_to_first_es);
362  cluster.set_layer2_last_es(layer2_pad_to_last_es);
363  cluster.set_layer2_middle_es(layer2_middle_es);
364 
365  if (station_ == 1) {
366  cluster.set_layer2_first_es_me1a(layer2_pad_to_first_es_me1a);
367  cluster.set_layer2_last_es_me1a(layer2_pad_to_last_es_me1a);
368  cluster.set_layer2_middle_es_me1a(layer2_middle_es_me1a);
369  }
370  }
371 
372  // calculate the wiregroups
373  // need to subtract 1 to use the LUTs
374  const int roll = cluster.roll2() - 1;
375 
376  int roll_l2_to_min_wg = -1;
377  int roll_l2_to_max_wg = -1;
378 
379  // ME1/1
380  if (station_ == 1) {
381  if (isEven_) {
382  roll_l2_to_min_wg = lookupTableME11ILT->GEM_roll_CSC_min_wg_ME11_even(roll);
383  roll_l2_to_max_wg = lookupTableME11ILT->GEM_roll_CSC_max_wg_ME11_even(roll);
384  } else {
385  roll_l2_to_min_wg = lookupTableME11ILT->GEM_roll_CSC_min_wg_ME11_odd(roll);
386  roll_l2_to_max_wg = lookupTableME11ILT->GEM_roll_CSC_max_wg_ME11_odd(roll);
387  }
388  }
389 
390  // ME2/1
391  if (station_ == 2) {
392  if (isEven_) {
393  roll_l2_to_min_wg = lookupTableME21ILT->GEM_roll_L2_CSC_min_wg_ME21_even(roll);
394  roll_l2_to_max_wg = lookupTableME21ILT->GEM_roll_L2_CSC_max_wg_ME21_even(roll);
395  } else {
396  roll_l2_to_min_wg = lookupTableME21ILT->GEM_roll_L2_CSC_min_wg_ME21_odd(roll);
397  roll_l2_to_max_wg = lookupTableME21ILT->GEM_roll_L2_CSC_max_wg_ME21_odd(roll);
398  }
399  }
400 
401  // set the values
402  cluster.set_layer2_min_wg(roll_l2_to_min_wg);
403  cluster.set_layer2_max_wg(roll_l2_to_max_wg);
404  }
405 }
406 
407 std::vector<GEMCoPadDigi> GEMClusterProcessor::readoutCoPads() const {
408  std::vector<GEMCoPadDigi> output;
409 
410  // loop on clusters
411  for (const auto& cluster : clusters_) {
412  // ignore single clusters
413  if (!cluster.isCoincidence())
414  continue;
415 
416  // construct coincidence pads out of the centers of the coincidence clusters
417  output.emplace_back(cluster.roll2(), cluster.mid1(), cluster.mid2());
418  }
419 
420  return output;
421 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
std::vector< GEMInternalCluster > clusters_
unsigned GEM_roll_L1_CSC_min_wg_ME21_even(unsigned roll) const
bool isME0(GeomDetEnumerators::SubDetector m)
unsigned GEM_roll_CSC_min_wg_ME11_odd(unsigned roll) const
unsigned GEM_pad_CSC_es_ME11b_odd(unsigned pad) const
std::vector< GEMInternalCluster > getClusters(int bx, ClusterTypes option=AllClusters) const
unsigned GEM_pad_CSC_es_ME21_even(unsigned pad) const
unsigned GEM_pad_CSC_es_ME11a_even(unsigned pad) const
unsigned GEM_roll_L1_CSC_max_wg_ME21_odd(unsigned roll) const
unsigned GEM_pad_CSC_es_ME11b_even(unsigned pad) const
unsigned int tmbL1aWindowSize_
unsigned GEM_pad_CSC_es_ME21_odd(unsigned pad) const
unsigned GEM_roll_CSC_min_wg_ME11_even(unsigned roll) const
unsigned GEM_roll_CSC_max_wg_ME11_even(unsigned roll) const
unsigned GEM_roll_L2_CSC_max_wg_ME21_odd(unsigned roll) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void run(const GEMPadDigiClusterCollection *, const CSCL1TPLookupTableME11ILT *lookupTableME11ILT, const CSCL1TPLookupTableME21ILT *lookupTableME21ILT)
void addSingleClusters(const GEMPadDigiClusterCollection *)
std::vector< GEMCoPadDigi > readoutCoPads() const
unsigned GEM_roll_L1_CSC_max_wg_ME21_even(unsigned roll) const
unsigned GEM_roll_L2_CSC_max_wg_ME21_even(unsigned roll) const
unsigned GEM_roll_L2_CSC_min_wg_ME21_even(unsigned roll) const
unsigned GEM_pad_CSC_es_ME11a_odd(unsigned pad) const
unsigned GEM_roll_CSC_max_wg_ME11_odd(unsigned roll) const
void addCoincidenceClusters(const GEMPadDigiClusterCollection *)
unsigned GEM_roll_L1_CSC_min_wg_ME21_odd(unsigned roll) const
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
Definition: output.py:1
unsigned GEM_roll_L2_CSC_min_wg_ME21_odd(unsigned roll) const
GEMClusterProcessor(int region, unsigned station, unsigned chamber, const edm::ParameterSet &conf)
Log< level::Warning, false > LogWarning
unsigned int delayGEMinOTMB_
void doCoordinateConversion(const CSCL1TPLookupTableME11ILT *lookupTableME11ILT, const CSCL1TPLookupTableME21ILT *lookupTableME21ILT)