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) {
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 
44 
46  // Step 1: clear the GEMInternalCluster vector
47  clear();
48 
49  if (in_clusters == nullptr) {
50  edm::LogWarning("GEMClusterProcessor") << "Attempt to run without valid in_clusters pointer.";
51  return;
52  }
53 
54  // Step 2: put coincidence clusters in GEMInternalCluster vector
55  addCoincidenceClusters(in_clusters);
56 
57  // Step 3: put single clusters in GEMInternalCluster vector who are not part of any coincidence cluster
58  addSingleClusters(in_clusters);
59 
60  // Step 4: translate the cluster central pad numbers into 1/8-strip number for matching with CSC trigger primitives
62 }
63 
64 std::vector<GEMInternalCluster> GEMClusterProcessor::getClusters(int bx, ClusterTypes option) const {
65  std::vector<GEMInternalCluster> output;
66 
67  for (const auto& cl : clusters_) {
68  // valid single clusters with the right BX
69  if (cl.bx() == bx and cl.isValid()) {
70  // ignore the coincidence clusters
71  if (option == SingleClusters and cl.isCoincidence())
72  continue;
73  // ignore the single clusters
74  if (option == CoincidenceClusters and !cl.isCoincidence())
75  continue;
76  output.push_back(cl);
77  }
78  }
79  return output;
80 }
81 
83  // Build coincidences
84  for (auto det_range = in_clusters->begin(); det_range != in_clusters->end(); ++det_range) {
85  const GEMDetId& id = (*det_range).first;
86 
87  // coincidence pads are not built for ME0
88  if (id.isME0())
89  continue;
90 
91  // same chamber (no restriction on the roll number)
92  if (id.region() != region_ or id.station() != station_ or id.chamber() != chamber_)
93  continue;
94 
95  // all coincidences detIDs will have layer=1
96  if (id.layer() != 1)
97  continue;
98 
99  // find all corresponding ids with layer 2 and same roll that differs at most maxDeltaRoll_
100  for (unsigned int roll = id.roll() - maxDeltaRoll_; roll <= id.roll() + maxDeltaRoll_; ++roll) {
101  GEMDetId co_id(id.region(), id.ring(), id.station(), 2, id.chamber(), roll);
102 
103  auto co_clusters_range = in_clusters->get(co_id);
104 
105  // empty range = no possible coincidence pads
106  if (co_clusters_range.first == co_clusters_range.second)
107  continue;
108 
109  // now let's correlate the pads in two layers of this partition
110  const auto& pads_range = (*det_range).second;
111  for (auto p = pads_range.first; p != pads_range.second; ++p) {
112  // ignore 8-partition GE2/1 pads
113  if (id.isGE21() and p->nPartitions() == GEMPadDigiCluster::GE21) {
115  continue;
116  }
117 
118  // only consider valid pads
119  if (!p->isValid())
120  continue;
121 
122  for (auto co_p = co_clusters_range.first; co_p != co_clusters_range.second; ++co_p) {
123  // only consider valid clusters
124  if (!co_p->isValid())
125  continue;
126 
127  // check the match in BX
128  if ((unsigned)std::abs(p->bx() - co_p->bx()) > maxDeltaBX_)
129  continue;
130 
131  // get the corrected minimum and maximum of cluster 1
132  int cl1_min = p->pads().front() - maxDeltaPad_;
133  int cl1_max = p->pads().back() + maxDeltaPad_;
134 
135  // get the minimum and maximum of cluster 2
136  int cl2_min = co_p->pads().front();
137  int cl2_max = co_p->pads().back();
138 
139  // match condition
140  const bool condition1(cl1_min <= cl2_min and cl1_max >= cl2_min);
141  const bool condition2(cl1_min <= cl2_max and cl1_max >= cl2_max);
142  const bool match(condition1 or condition2);
143 
144  if (!match)
145  continue;
146 
147  // make a new coincidence
148  clusters_.emplace_back(id, co_id, *p, *co_p, delayGEMinOTMB_, tmbL1aWindowSize_);
149  // std::cout << clusters_.back() << std::endl;
150  }
151  }
152  }
153  }
154 }
155 
157  // first get the coincidences
158  const std::vector<GEMInternalCluster>& coincidences = clusters_;
159 
160  // now start add single clusters
161  for (auto det_range = in_clusters->begin(); det_range != in_clusters->end(); ++det_range) {
162  const GEMDetId& id = (*det_range).first;
163 
164  // ignore ME0
165  if (id.isME0())
166  continue;
167 
168  // same chamber (no restriction on the roll number)
169  if (id.region() != region_ or id.station() != station_ or id.chamber() != chamber_)
170  continue;
171 
172  const auto& clusters_range = (*det_range).second;
173  for (auto p = clusters_range.first; p != clusters_range.second; ++p) {
174  // only consider valid clusters
175  if (!p->isValid())
176  continue;
177 
178  // ignore 8-partition GE2/1 pads
179  if (id.isGE21() and p->nPartitions() == GEMPadDigiCluster::GE21) {
181  continue;
182  }
183 
184  // ignore clusters already contained in a coincidence cluster
185  if (std::find_if(std::begin(coincidences), std::end(coincidences), [p](const GEMInternalCluster& q) {
186  return q.has_cluster(*p);
187  }) != std::end(coincidences))
188  continue;
189 
190  // put the single clusters into the collection
191  if (id.layer() == 1) {
192  clusters_.emplace_back(id, id, *p, GEMPadDigiCluster(), delayGEMinOTMB_, tmbL1aWindowSize_);
193  // std::cout << clusters_.back() << std::endl;
194  } else {
195  clusters_.emplace_back(id, id, GEMPadDigiCluster(), *p, delayGEMinOTMB_, tmbL1aWindowSize_);
196  // std::cout << clusters_.back() << std::endl;
197  }
198  }
199  }
200 }
201 
203  // loop on clusters
204  for (auto& cluster : clusters_) {
205  if (cluster.cl1().isValid()) {
206  // starting coordinates
207  const int layer1_first_pad = cluster.layer1_pad();
208  const int layer1_last_pad = layer1_first_pad + cluster.layer1_size() - 1;
209 
210  // calculate the 1/8-strips
211  int layer1_pad_to_first_es = -1;
212  int layer1_pad_to_last_es = -1;
213 
214  int layer1_pad_to_first_es_me1a = -1;
215  int layer1_pad_to_last_es_me1a = -1;
216 
217  // ME1/1
218  if (station_ == 1) {
219  if (isEven_) {
220  // ME1/b
221  layer1_pad_to_first_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_even(layer1_first_pad);
222  layer1_pad_to_last_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_even(layer1_last_pad);
223  // ME1/a
224  layer1_pad_to_first_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_even(layer1_first_pad);
225  layer1_pad_to_last_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_even(layer1_last_pad);
226  } else {
227  // ME1/b
228  layer1_pad_to_first_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_odd(layer1_first_pad);
229  layer1_pad_to_last_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_odd(layer1_last_pad);
230  // ME1/a
231  layer1_pad_to_first_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_odd(layer1_first_pad);
232  layer1_pad_to_last_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_odd(layer1_last_pad);
233  }
234  }
235  // ME2/1
236  if (station_ == 2) {
237  if (isEven_) {
238  layer1_pad_to_first_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_even(layer1_first_pad);
239  layer1_pad_to_last_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_even(layer1_last_pad);
240  } else {
241  layer1_pad_to_first_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_odd(layer1_first_pad);
242  layer1_pad_to_last_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_odd(layer1_last_pad);
243  }
244  }
245  // middle 1/8-strip
246  int layer1_middle_es = (layer1_pad_to_first_es + layer1_pad_to_last_es) / 2.;
247  int layer1_middle_es_me1a = (layer1_pad_to_first_es_me1a + layer1_pad_to_last_es_me1a) / 2.;
248 
249  cluster.set_layer1_first_es(layer1_pad_to_first_es);
250  cluster.set_layer1_last_es(layer1_pad_to_last_es);
251  cluster.set_layer1_middle_es(layer1_middle_es);
252 
253  if (station_ == 1) {
254  cluster.set_layer1_first_es_me1a(layer1_pad_to_first_es_me1a);
255  cluster.set_layer1_last_es_me1a(layer1_pad_to_last_es_me1a);
256  cluster.set_layer1_middle_es_me1a(layer1_middle_es_me1a);
257  }
258 
259  // calculate the wiregroups
260  // need to subtract 1 to use the LUTs
261  const int roll = cluster.roll1() - 1;
262 
263  int roll_l1_to_min_wg = -1;
264  int roll_l1_to_max_wg = -1;
265 
266  // ME1/1
267  if (station_ == 1) {
268  if (isEven_) {
269  roll_l1_to_min_wg = lookupTableME11ILT_->GEM_roll_CSC_min_wg_ME11_even(roll);
270  roll_l1_to_max_wg = lookupTableME11ILT_->GEM_roll_CSC_max_wg_ME11_even(roll);
271  } else {
272  roll_l1_to_min_wg = lookupTableME11ILT_->GEM_roll_CSC_min_wg_ME11_odd(roll);
273  roll_l1_to_max_wg = lookupTableME11ILT_->GEM_roll_CSC_max_wg_ME11_odd(roll);
274  }
275  }
276 
277  // ME2/1
278  if (station_ == 2) {
279  if (isEven_) {
280  roll_l1_to_min_wg = lookupTableME21ILT_->GEM_roll_L1_CSC_min_wg_ME21_even(roll);
281  roll_l1_to_max_wg = lookupTableME21ILT_->GEM_roll_L1_CSC_max_wg_ME21_even(roll);
282  } else {
283  roll_l1_to_min_wg = lookupTableME21ILT_->GEM_roll_L1_CSC_min_wg_ME21_odd(roll);
284  roll_l1_to_max_wg = lookupTableME21ILT_->GEM_roll_L1_CSC_max_wg_ME21_odd(roll);
285  }
286  }
287 
288  // set the values
289  cluster.set_layer1_min_wg(roll_l1_to_min_wg);
290  cluster.set_layer1_max_wg(roll_l1_to_max_wg);
291  }
292 
293  if (cluster.cl2().isValid()) {
294  // starting coordinates
295  const int layer2_first_pad = cluster.layer2_pad();
296  const int layer2_last_pad = layer2_first_pad + cluster.layer2_size() - 1;
297 
298  // calculate the 1/8-strips
299  int layer2_pad_to_first_es = -1;
300  int layer2_pad_to_last_es = -1;
301 
302  int layer2_pad_to_first_es_me1a = -1;
303  int layer2_pad_to_last_es_me1a = -1;
304 
305  if (station_ == 1) {
306  if (isEven_) {
307  // ME1/b
308  layer2_pad_to_first_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_even(layer2_first_pad);
309  layer2_pad_to_last_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_even(layer2_last_pad);
310  // ME1/a
311  layer2_pad_to_first_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_even(layer2_first_pad);
312  layer2_pad_to_last_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_even(layer2_last_pad);
313  } else {
314  // ME1/b
315  layer2_pad_to_first_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_odd(layer2_first_pad);
316  layer2_pad_to_last_es = lookupTableME11ILT_->GEM_pad_CSC_es_ME11b_odd(layer2_last_pad);
317  // ME1/a
318  layer2_pad_to_first_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_odd(layer2_first_pad);
319  layer2_pad_to_last_es_me1a = lookupTableME11ILT_->GEM_pad_CSC_es_ME11a_odd(layer2_last_pad);
320  }
321  }
322 
323  // ME2/1
324  if (station_ == 2) {
325  if (isEven_) {
326  layer2_pad_to_first_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_even(layer2_first_pad);
327  layer2_pad_to_last_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_even(layer2_last_pad);
328  } else {
329  layer2_pad_to_first_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_odd(layer2_first_pad);
330  layer2_pad_to_last_es = lookupTableME21ILT_->GEM_pad_CSC_es_ME21_odd(layer2_last_pad);
331  }
332  }
333  // middle 1/8-strip
334  int layer2_middle_es = int((layer2_pad_to_first_es + layer2_pad_to_last_es) / 2.0);
335  int layer2_middle_es_me1a = int((layer2_pad_to_first_es_me1a + layer2_pad_to_last_es_me1a) / 2.0);
336 
337  cluster.set_layer2_first_es(layer2_pad_to_first_es);
338  cluster.set_layer2_last_es(layer2_pad_to_last_es);
339  cluster.set_layer2_middle_es(layer2_middle_es);
340 
341  if (station_ == 1) {
342  cluster.set_layer2_first_es_me1a(layer2_pad_to_first_es_me1a);
343  cluster.set_layer2_last_es_me1a(layer2_pad_to_last_es_me1a);
344  cluster.set_layer2_middle_es_me1a(layer2_middle_es_me1a);
345  }
346  }
347 
348  // calculate the wiregroups
349  // need to subtract 1 to use the LUTs
350  const int roll = cluster.roll2() - 1;
351 
352  int roll_l2_to_min_wg = -1;
353  int roll_l2_to_max_wg = -1;
354 
355  // ME1/1
356  if (station_ == 1) {
357  if (isEven_) {
358  roll_l2_to_min_wg = lookupTableME11ILT_->GEM_roll_CSC_min_wg_ME11_even(roll);
359  roll_l2_to_max_wg = lookupTableME11ILT_->GEM_roll_CSC_max_wg_ME11_even(roll);
360  } else {
361  roll_l2_to_min_wg = lookupTableME11ILT_->GEM_roll_CSC_min_wg_ME11_odd(roll);
362  roll_l2_to_max_wg = lookupTableME11ILT_->GEM_roll_CSC_max_wg_ME11_odd(roll);
363  }
364  }
365 
366  // ME2/1
367  if (station_ == 2) {
368  if (isEven_) {
369  roll_l2_to_min_wg = lookupTableME21ILT_->GEM_roll_L2_CSC_min_wg_ME21_even(roll);
370  roll_l2_to_max_wg = lookupTableME21ILT_->GEM_roll_L2_CSC_max_wg_ME21_even(roll);
371  } else {
372  roll_l2_to_min_wg = lookupTableME21ILT_->GEM_roll_L2_CSC_min_wg_ME21_odd(roll);
373  roll_l2_to_max_wg = lookupTableME21ILT_->GEM_roll_L2_CSC_max_wg_ME21_odd(roll);
374  }
375  }
376 
377  // set the values
378  cluster.set_layer2_min_wg(roll_l2_to_min_wg);
379  cluster.set_layer2_max_wg(roll_l2_to_max_wg);
380  }
381 }
382 
383 std::vector<GEMCoPadDigi> GEMClusterProcessor::readoutCoPads() const {
384  std::vector<GEMCoPadDigi> output;
385 
386  // loop on clusters
387  for (const auto& cluster : clusters_) {
388  // ignore single clusters
389  if (!cluster.isCoincidence())
390  continue;
391 
392  // construct coincidence pads out of the centers of the coincidence clusters
393  output.emplace_back(cluster.roll2(), cluster.mid1(), cluster.mid2());
394  }
395 
396  return output;
397 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::vector< GEMInternalCluster > clusters_
unsigned GEM_roll_L1_CSC_min_wg_ME21_even(unsigned roll) const
void run(const GEMPadDigiClusterCollection *)
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
constexpr std::array< uint8_t, layerIndexSize > layer
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 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
const CSCL1TPLookupTableME21ILT * lookupTableME21ILT_
void setESLookupTables(const CSCL1TPLookupTableME11ILT *conf)
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
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_
const CSCL1TPLookupTableME11ILT * lookupTableME11ILT_