CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CSCGEMMotherboard.cc
Go to the documentation of this file.
1 #include <memory>
2 
5  unsigned station,
6  unsigned sector,
7  unsigned subsector,
8  unsigned chamber,
9  const edm::ParameterSet& conf)
10  : CSCMotherboard(endcap, station, sector, subsector, chamber, conf),
11  drop_low_quality_alct_no_gems_(tmbParams_.getParameter<bool>("dropLowQualityALCTsNoGEMs")),
12  drop_low_quality_clct_no_gems_(tmbParams_.getParameter<bool>("dropLowQualityCLCTsNoGEMs")),
13  build_lct_from_alct_clct_2gem_(tmbParams_.getParameter<bool>("buildLCTfromALCTCLCTand2GEM")),
14  build_lct_from_alct_clct_1gem_(tmbParams_.getParameter<bool>("buildLCTfromALCTCLCTand1GEM")),
15  build_lct_from_alct_gem_(tmbParams_.getParameter<bool>("buildLCTfromALCTandGEM")),
16  build_lct_from_clct_gem_(tmbParams_.getParameter<bool>("buildLCTfromCLCTandGEM")) {
17  // case for ME1/1
18  if (isME11_) {
19  drop_low_quality_clct_no_gems_me1a_ = tmbParams_.getParameter<bool>("dropLowQualityCLCTsNoGEMs_ME1a");
20  build_lct_from_clct_gem_me1a_ = tmbParams_.getParameter<bool>("buildLCTfromCLCTandGEM_ME1a");
21  }
22 
23  max_delta_bx_alct_gem_ = tmbParams_.getParameter<unsigned>("maxDeltaBXALCTGEM");
24  max_delta_bx_clct_gem_ = tmbParams_.getParameter<unsigned>("maxDeltaBXCLCTGEM");
25 
26  assign_gem_csc_bending_ = tmbParams_.getParameter<bool>("assignGEMCSCBending");
27  qualityAssignment_->setGEMCSCBending(assign_gem_csc_bending_);
28 
29  drop_used_gems_ = tmbParams_.getParameter<bool>("tmbDropUsedGems");
30  match_earliest_gem_only_ = tmbParams_.getParameter<bool>("matchEarliestGemsOnly");
31 
32  // These LogErrors are sanity checks and should not be printed
33  if (isME11_ and !runME11ILT_) {
34  edm::LogError("CSCGEMMotherboard") << "TMB constructed while runME11ILT_ is not set!";
35  };
36 
37  if (isME21_ and !runME21ILT_) {
38  edm::LogError("CSCGEMMotherboard") << "TMB constructed while runME21ILT_ is not set!";
39  };
40 
41  // These LogErrors are sanity checks and should not be printed
42  if (!isME11_ and !isME21_) {
43  edm::LogError("CSCGEMMotherboard") << "GEM-CSC OTMB constructed for a non-ME1/1 or a non-ME2/1 chamber!";
44  };
45 
46  // super chamber has layer=0!
48 
49  clusterProc_ = std::make_shared<GEMClusterProcessor>(theRegion, theStation, theChamber, conf);
50 
51  cscGEMMatcher_ = std::make_unique<CSCGEMMatcher>(theRegion, theStation, theChamber, tmbParams_, conf);
52 }
53 
55 
58  clusterProc_->clear();
59 }
60 
62  const CSCComparatorDigiCollection* compdc,
63  const GEMPadDigiClusterCollection* gemClusters) {
64  // Step 1: Setup
65  clear();
66 
67  // Check that the processors can deliver data
68  if (!(alctProc and clctProc)) {
69  edm::LogError("CSCGEMMotherboard") << "run() called for non-existing ALCT/CLCT processor in " << theCSCName_;
70  return;
71  }
72 
73  // set geometry
74  alctProc->setCSCGeometry(cscGeometry_);
75  clctProc->setCSCGeometry(cscGeometry_);
76 
77  // set CCLUT parameters if necessary
78  if (runCCLUT_) {
79  clctProc->setESLookupTables(lookupTableCCLUT_);
80  }
81 
82  // Step 2: Run the processors
83  const std::vector<CSCALCTDigi>& alctV = alctProc->run(wiredc); // run anodeLCT
84  const std::vector<CSCCLCTDigi>& clctV = clctProc->run(compdc); // run cathodeLCT
85 
86  // Step 2b: encode high multiplicity bits (independent of LCT construction)
88 
89  // if there are no ALCTs and no CLCTs, do not run the ALCT-CLCT correlation
90  if (alctV.empty() and clctV.empty())
91  return;
92 
93  bool validClustersAndGeometry = true;
94 
95  // Step 3a: check for GEM geometry
96  if (gem_g == nullptr) {
97  edm::LogWarning("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger"
98  << " without valid GEM geometry! Running CSC-only"
99  << " trigger algorithm in " << theCSCName_;
100  validClustersAndGeometry = false;
101  }
102 
103  // Step 3b: check that the GEM cluster collection is a valid pointer
104  if (gemClusters == nullptr) {
105  edm::LogWarning("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger"
106  << " without valid GEM clusters! Running CSC-only"
107  << " trigger algorithm in " << theCSCName_;
108  validClustersAndGeometry = false;
109  }
110 
111  if (validClustersAndGeometry) {
112  // Step 3c: set the lookup tables for coordinate conversion and matching
113  if (isME11_) {
114  clusterProc_->setESLookupTables(lookupTableME11ILT_);
115  cscGEMMatcher_->setESLookupTables(lookupTableME11ILT_);
116  }
117  if (isME21_) {
118  clusterProc_->setESLookupTables(lookupTableME21ILT_);
119  cscGEMMatcher_->setESLookupTables(lookupTableME21ILT_);
120  }
121 
122  // Step 3d: run the GEM cluster processor to get the internal clusters
123  clusterProc_->run(gemClusters);
124  hasGE21Geometry16Partitions_ = clusterProc_->hasGE21Geometry16Partitions();
125  }
126 
127  /*
128  Mask for bunch crossings were LCTs were previously found
129  If LCTs were found in BXi for ALCT-CLCT-2GEM or ALCT-CLCT-1GEM,
130  we do not consider BXi in the future. This is
131  because we consider ALCT-CLCT-2GEM > ALCT-CLCT-1GEM > ALCT-CLCT
132  > CLCT-2GEM > ALCT-2GEM. The mask is passsed from one function to the next.
133  */
134  bool bunch_crossing_mask[CSCConstants::MAX_ALCT_TBINS] = {false};
135 
136  // Step 4: ALCT-CLCT-2GEM and ALCT-CLCT-1GEM matching
138  matchALCTCLCTGEM(bunch_crossing_mask);
139  }
140 
141  // Step 5: regular ALCT-CLCT matching (always enabled)
142  CSCMotherboard::matchALCTCLCT(bunch_crossing_mask);
143 
144  // Step 6: CLCT-2GEM matching for BX's that were not previously masked
145  if (build_lct_from_clct_gem_ and validClustersAndGeometry) {
146  matchCLCT2GEM(bunch_crossing_mask);
147  }
148 
149  // Step 7: ALCT-2GEM matching for BX's that were not previously masked
150  if (build_lct_from_alct_gem_ and validClustersAndGeometry) {
151  matchALCT2GEM(bunch_crossing_mask);
152  }
153 
154  // Step 8: Select at most 2 LCTs per BX
155  selectLCTs();
156 }
157 
159  // no matching is done for GE2/1 geometries with 8 eta partitions
160  // this has been superseded by 16-eta partition geometries
162  return;
163 
164  // by default we will try to match with both single clusters and coincidence clusters
165  // if we do not build ALCT-CLCT-2GEM type LCTs, consider only single clusters
169 
170  // array to mask CLCTs
171  bool used_clct_mask[CSCConstants::MAX_CLCT_TBINS] = {false};
172 
173  for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS; bx_alct++) {
174  // do not consider invalid ALCTs
175  if (alctProc->getBestALCT(bx_alct).isValid()) {
176  for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) {
177  // evaluate the preffered CLCT BX, taking into account that there is an offset in the simulation
178  unsigned bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
179 
180  // CLCT BX must be in the time window
181  if (bx_clct >= CSCConstants::MAX_CLCT_TBINS)
182  continue;
183  // drop this CLCT if it was previously matched to an ALCT
184  if (drop_used_clcts and used_clct_mask[bx_clct])
185  continue;
186  // do not consider invalid CLCTs
187  if (clctProc->getBestCLCT(bx_clct).isValid()) {
188  LogTrace("CSCMotherboard") << "Successful ALCT-CLCT match: bx_alct = " << bx_alct << "; bx_clct = " << bx_clct
189  << "; mbx = " << mbx;
190 
191  // now correlate the ALCT and CLCT into LCT.
192  // smaller mbx means more preferred!
193  correlateLCTsGEM(alctProc->getBestALCT(bx_alct),
194  alctProc->getSecondALCT(bx_alct),
195  clctProc->getBestCLCT(bx_clct),
196  clctProc->getSecondCLCT(bx_clct),
197  clusterProc_->getClusters(bx_alct, max_delta_bx_alct_gem_, option),
198  allLCTs_(bx_alct, mbx, 0),
199  allLCTs_(bx_alct, mbx, 1));
200 
201  if (allLCTs_(bx_alct, mbx, 0).isValid()) {
202  // mask this CLCT as used. If a flag is set, the CLCT may or may not be reused
203  used_clct_mask[bx_clct] = true;
204  // mask this bunch crossing for future considation
205  bunch_crossing_mask[bx_alct] = true;
206  // if we only consider the first valid CLCT, we move on to the next ALCT immediately
208  break;
209  }
210  }
211  }
212  }
213  }
214 }
215 
217  // no matching is done for GE2/1 geometries with 8 eta partitions
218  // this has been superseded by 16-eta partition geometries
220  return;
221 
222  // array to mask CLCTs
223  bool used_clct_mask[CSCConstants::MAX_CLCT_TBINS] = {false};
224 
225  for (int bx_gem = 0; bx_gem < CSCConstants::MAX_ALCT_TBINS; bx_gem++) {
226  // do not consider LCT building in this BX if the mask was set
227  if (bunch_crossing_mask[bx_gem])
228  continue;
229 
230  // Check that there is at least one valid GEM coincidence cluster in this BX
231  if (!clusterProc_->getCoincidenceClusters(bx_gem).empty()) {
232  // GEM clusters will have central BX 8. So do ALCTs. But! CLCTs still have central BX 7
233  // therefore we need to make a correction. The correction is thus the same as for ALCT-CLCT
234  for (unsigned mbx = 0; mbx < 2 * max_delta_bx_clct_gem_ + 1; mbx++) {
235  // evaluate the preffered CLCT BX, taking into account that there is an offset in the simulation
236  int bx_clct = bx_gem + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
237 
238  // CLCT BX must be in the time window
239  if (bx_clct < 0 or bx_clct >= CSCConstants::MAX_CLCT_TBINS)
240  continue;
241  // drop this CLCT if it was previously matched to a GEM coincidence cluster
242  if (drop_used_clcts and used_clct_mask[bx_clct])
243  continue;
244  // do not consider invalid CLCTs
245  if (clctProc->getBestCLCT(bx_clct).isValid()) {
246  // if this is an ME1/a CLCT, you could consider not building this LCT
248  clctProc->getBestCLCT(bx_clct).getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B)
249  continue;
250  // mbx is a relative time difference, which is used later in the
251  // cross-bunching sorting algorithm to determine the preferred LCTs
252  // to be sent to the MPC
253  correlateLCTsGEM(clctProc->getBestCLCT(bx_clct),
254  clctProc->getSecondCLCT(bx_clct),
255  clusterProc_->getCoincidenceClusters(bx_gem),
256  allLCTs_(bx_gem, mbx, 0),
257  allLCTs_(bx_gem, mbx, 1));
258 
259  if (allLCTs_(bx_gem, mbx, 0).isValid()) {
260  // do not consider GEM clusters
261  used_clct_mask[bx_clct] = true;
262  // mask this bunch crossing for future consideration
263  bunch_crossing_mask[bx_gem] = true;
264  // if we only consider the first valid GEM coincidence clusters,
265  // we move on to the next ALCT immediately
267  break;
268  }
269  }
270  }
271  }
272  }
273 }
274 
276  // no matching is done for GE2/1 geometries with 8 eta partitions
277  // this has been superseded by 16-eta partition geometries
279  return;
280 
281  // clear the array to mask GEMs this window is quite wide.
282  // We don't expect GEM coincidence clusters to show up too far
283  // from the central BX (8)
284  bool used_gem_mask[CSCConstants::MAX_ALCT_TBINS] = {false};
285 
286  for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS; bx_alct++) {
287  // do not consider LCT building in this BX if the mask was set
288  if (bunch_crossing_mask[bx_alct])
289  continue;
290 
291  if (alctProc->getBestALCT(bx_alct).isValid()) {
292  for (unsigned mbx = 0; mbx < 2 * max_delta_bx_alct_gem_ + 1; mbx++) {
293  // evaluate the preffered GEM BX
294  int bx_gem = bx_alct + preferred_bx_match_[mbx];
295 
296  if (bx_gem < 0 or bx_gem >= CSCConstants::MAX_ALCT_TBINS)
297  continue;
298  // drop GEMs in this BX if one of them was previously matched to an ALCT
299  if (drop_used_gems_ and used_gem_mask[bx_gem])
300  continue;
301  // check for at least one valid GEM cluster
302  if (!clusterProc_->getCoincidenceClusters(bx_gem).empty()) {
303  // now correlate the ALCT and GEM into LCT.
304  // smaller mbx means more preferred!
305  correlateLCTsGEM(alctProc->getBestALCT(bx_alct),
306  alctProc->getSecondALCT(bx_alct),
307  clusterProc_->getCoincidenceClusters(bx_gem),
308  allLCTs_(bx_alct, mbx, 0),
309  allLCTs_(bx_alct, mbx, 1));
310 
311  if (allLCTs_(bx_alct, mbx, 0).isValid()) {
312  // do not consider GEM clusters
313  used_gem_mask[bx_gem] = true;
314  // mask this bunch crossing for future consideration
315  bunch_crossing_mask[bx_alct] = true;
316  // if we only consider the first valid GEM coincidence clusters,
317  // we move on to the next ALCT immediately
319  break;
320  }
321  }
322  }
323  }
324  }
325 }
326 
328  const CSCALCTDigi& sALCT,
329  const CSCCLCTDigi& bCLCT,
330  const CSCCLCTDigi& sCLCT,
332  CSCCorrelatedLCTDigi& lct1,
333  CSCCorrelatedLCTDigi& lct2) const {
334  // case where there no valid clusters
335  if (clusters.empty())
336  return;
337 
338  // temporary container
339  std::vector<CSCCorrelatedLCTDigi> lcts;
340 
341  CSCALCTDigi bestALCT = bALCT;
342  CSCALCTDigi secondALCT = sALCT;
343  CSCCLCTDigi bestCLCT = bCLCT;
344  CSCCLCTDigi secondCLCT = sCLCT;
345 
346  // Sanity checks on the ALCT and CLCT
347  if (!bestALCT.isValid()) {
348  edm::LogError("CSCGEMMotherboard") << "Best ALCT invalid in correlateLCTsGEM!";
349  return;
350  }
351 
352  if (!bestCLCT.isValid()) {
353  edm::LogError("CSCGEMMotherboard") << "Best CLCT invalid in correlateLCTsGEM!";
354  return;
355  }
356 
357  // at this point, we have at least one valid cluster, and we're either dealing
358  // wit GE1/1 or GE2/1 with 16 partitions, both are OK for GEM-CSC trigger
359 
360  // before matching ALCT-CLCT pairs with clusters, we check if we need
361  // to drop particular low quality ALCTs or CLCTs without matching clusters
362  // drop low quality CLCTs if no clusters and flags are set
363  GEMInternalCluster bestALCTCluster, secondALCTCluster;
364  GEMInternalCluster bestCLCTCluster, secondCLCTCluster;
365  cscGEMMatcher_->bestClusterBXLoc(bestALCT, clusters, bestALCTCluster);
366  cscGEMMatcher_->bestClusterBXLoc(secondALCT, clusters, secondALCTCluster);
367  cscGEMMatcher_->bestClusterBXLoc(bestCLCT, clusters, bestCLCTCluster);
368  cscGEMMatcher_->bestClusterBXLoc(secondCLCT, clusters, secondCLCTCluster);
369 
370  dropLowQualityALCTNoClusters(bestALCT, bestALCTCluster);
371  dropLowQualityALCTNoClusters(secondALCT, secondALCTCluster);
372  dropLowQualityCLCTNoClusters(bestCLCT, bestCLCTCluster);
373  dropLowQualityCLCTNoClusters(secondCLCT, secondCLCTCluster);
374 
375  // check which ALCTs and CLCTs are valid after dropping the low-quality ones
376  copyValidToInValid(bestALCT, secondALCT, bestCLCT, secondCLCT);
377 
378  // We can now check possible triplets and construct all LCTs with
379  // valid ALCT, valid CLCTs and coincidence clusters
380  GEMInternalCluster bbCluster, bsCluster, sbCluster, ssCluster;
381  cscGEMMatcher_->bestClusterBXLoc(bestALCT, bestCLCT, clusters, bbCluster);
382  cscGEMMatcher_->bestClusterBXLoc(bestALCT, secondCLCT, clusters, bsCluster);
383  cscGEMMatcher_->bestClusterBXLoc(secondALCT, bestCLCT, clusters, sbCluster);
384  cscGEMMatcher_->bestClusterBXLoc(secondALCT, secondCLCT, clusters, ssCluster);
385 
386  // At this point it is still possible that certain pairs with high-quality
387  // ALCTs and CLCTs do not have matching clusters. In that case we construct
388  // a regular ALCT-CLCT type LCT. For instance, it could be that two muons went
389  // through the chamber, produced 2 ALCTs, 2 CLCTs, but only 1 GEM cluster - because
390  // GEM cluster efficiency is not 100% (closer to 95%). So we don't require
391  // all clusters to be valid. If they are valid, the LCTs is constructed accordingly.
392  // But we do require that the ALCT and CLCT are valid for each pair.
393  CSCCorrelatedLCTDigi lctbb, lctbs, lctsb, lctss;
394  if (bestALCT.isValid() and bestCLCT.isValid()) {
395  constructLCTsGEM(bestALCT, bestCLCT, bbCluster, lctbb);
396  lcts.push_back(lctbb);
397  }
398  if (bestALCT.isValid() and secondCLCT.isValid() and (secondCLCT != bestCLCT)) {
399  constructLCTsGEM(bestALCT, secondCLCT, bsCluster, lctbs);
400  lcts.push_back(lctbs);
401  }
402  if (bestCLCT.isValid() and secondALCT.isValid() and (secondALCT != bestALCT)) {
403  constructLCTsGEM(secondALCT, bestCLCT, sbCluster, lctsb);
404  lcts.push_back(lctsb);
405  }
406  if (secondALCT.isValid() and secondCLCT.isValid() and (secondALCT != bestALCT) and (secondCLCT != bestCLCT)) {
407  constructLCTsGEM(secondALCT, secondCLCT, ssCluster, lctss);
408  lcts.push_back(lctss);
409  }
410 
411  // no LCTs
412  if (lcts.empty())
413  return;
414 
415  // sort by bending angle
416  sortLCTsByBending(lcts);
417 
418  // retain best two
419  lcts.resize(CSCConstants::MAX_LCTS_PER_CSC);
420 
421  // assign the track number
422  if (lcts[0].isValid()) {
423  lct1 = lcts[0];
424  lct1.setTrknmb(1);
425  }
426 
427  if (lcts[1].isValid()) {
428  lct2 = lcts[1];
429  lct2.setTrknmb(2);
430  }
431 }
432 
434  const CSCCLCTDigi& sCLCT,
436  CSCCorrelatedLCTDigi& lct1,
437  CSCCorrelatedLCTDigi& lct2) const {
438  CSCCLCTDigi bestCLCT = bCLCT;
439  CSCCLCTDigi secondCLCT = sCLCT;
440 
441  if (!bestCLCT.isValid()) {
442  edm::LogError("CSCGEMMotherboard") << "Best CLCT invalid in correlateLCTsGEM!";
443  return;
444  }
445 
446  // if the second best CLCT equals the best CLCT, clear it
447  if (secondCLCT == bestCLCT)
448  secondCLCT.clear();
449 
450  // get the best matching cluster
451  GEMInternalCluster bestCluster;
452  GEMInternalCluster secondCluster;
453  cscGEMMatcher_->bestClusterBXLoc(bestCLCT, clusters, bestCluster);
454  cscGEMMatcher_->bestClusterBXLoc(secondCLCT, clusters, secondCluster);
455 
456  // drop low quality CLCTs if no clusters and flags are set
457  dropLowQualityCLCTNoClusters(bestCLCT, bestCluster);
458  dropLowQualityCLCTNoClusters(secondCLCT, secondCluster);
459 
460  // construct all LCTs with valid CLCTs and coincidence clusters
461  if (bestCLCT.isValid() and bestCluster.isCoincidence()) {
462  constructLCTsGEM(bestCLCT, bestCluster, 1, lct1);
463  }
464  if (secondCLCT.isValid() and secondCluster.isCoincidence()) {
465  constructLCTsGEM(secondCLCT, secondCluster, 2, lct2);
466  }
467 }
468 
470  const CSCALCTDigi& sALCT,
472  CSCCorrelatedLCTDigi& lct1,
473  CSCCorrelatedLCTDigi& lct2) const {
474  CSCALCTDigi bestALCT = bALCT;
475  CSCALCTDigi secondALCT = sALCT;
476 
477  if (!bestALCT.isValid()) {
478  edm::LogError("CSCGEMMotherboard") << "Best ALCT invalid in correlateLCTsGEM!";
479  return;
480  }
481 
482  // if the second best ALCT equals the best ALCT, clear it
483  if (secondALCT == bestALCT)
484  secondALCT.clear();
485 
486  // get the best matching cluster
487  GEMInternalCluster bestCluster;
488  GEMInternalCluster secondCluster;
489  cscGEMMatcher_->bestClusterBXLoc(bestALCT, clusters, bestCluster);
490  cscGEMMatcher_->bestClusterBXLoc(secondALCT, clusters, secondCluster);
491 
492  // drop low quality ALCTs if no clusters and flags are set
493  dropLowQualityALCTNoClusters(bestALCT, bestCluster);
494  dropLowQualityALCTNoClusters(secondALCT, secondCluster);
495 
496  // construct all LCTs with valid ALCTs and coincidence clusters
497  if (bestALCT.isValid() and bestCluster.isCoincidence()) {
498  constructLCTsGEM(bestALCT, bestCluster, 1, lct1);
499  }
500  if (secondALCT.isValid() and secondCluster.isCoincidence()) {
501  constructLCTsGEM(secondALCT, secondCluster, 2, lct2);
502  }
503 }
504 
506  const CSCCLCTDigi& clct,
507  const GEMInternalCluster& gem,
508  CSCCorrelatedLCTDigi& thisLCT) const {
509  thisLCT.setValid(true);
510  if (gem.isCoincidence()) {
512  } else if (gem.isValid()) {
514  } else {
516  }
517  thisLCT.setQuality(qualityAssignment_->findQuality(alct, clct, gem));
518  thisLCT.setALCT(getBXShiftedALCT(alct));
519  thisLCT.setCLCT(getBXShiftedCLCT(clct));
520  // set pads if there are any
521  thisLCT.setGEM1(gem.mid1());
522  thisLCT.setGEM2(gem.mid2());
523  thisLCT.setPattern(encodePattern(clct.getPattern()));
524  thisLCT.setMPCLink(0);
525  thisLCT.setBX0(0);
526  thisLCT.setSyncErr(0);
527  thisLCT.setCSCID(theTrigChamber);
528  // track number to be set later in final sorting stage
529  thisLCT.setTrknmb(0);
530  thisLCT.setWireGroup(alct.getKeyWG());
531  thisLCT.setStrip(clct.getKeyStrip());
532  thisLCT.setBend(clct.getBend());
533  thisLCT.setBX(alct.getBX());
534  if (runCCLUT_) {
535  thisLCT.setRun3(true);
537  thisLCT.setSlope(cscGEMMatcher_->calculateGEMCSCBending(clct, gem));
538  else
539  thisLCT.setSlope(clct.getSlope());
540  thisLCT.setQuartStripBit(clct.getQuartStripBit());
541  thisLCT.setEighthStripBit(clct.getEighthStripBit());
542  thisLCT.setRun3Pattern(clct.getRun3Pattern());
543  }
544 }
545 
546 /* Construct LCT from CSC and GEM information. Option CLCT-2GEM */
548  const GEMInternalCluster& gem,
549  int trackNumber,
550  CSCCorrelatedLCTDigi& thisLCT) const {
551  thisLCT.setValid(true);
553  thisLCT.setQuality(qualityAssignment_->findQuality(clct, gem));
554  thisLCT.setCLCT(getBXShiftedCLCT(clct));
555  thisLCT.setGEM1(gem.mid1());
556  thisLCT.setGEM2(gem.mid2());
557  thisLCT.setPattern(encodePattern(clct.getPattern()));
558  thisLCT.setMPCLink(0);
559  thisLCT.setBX0(0);
560  thisLCT.setSyncErr(0);
561  thisLCT.setCSCID(theTrigChamber);
562  thisLCT.setTrknmb(trackNumber);
563  thisLCT.setWireGroup(gem.getKeyWG());
564  thisLCT.setStrip(clct.getKeyStrip());
565  thisLCT.setBend(clct.getBend());
566  thisLCT.setBX(gem.bx());
567  if (runCCLUT_) {
568  thisLCT.setRun3(true);
570  thisLCT.setSlope(cscGEMMatcher_->calculateGEMCSCBending(clct, gem));
571  else
572  thisLCT.setSlope(clct.getSlope());
573  thisLCT.setQuartStripBit(clct.getQuartStripBit());
574  thisLCT.setEighthStripBit(clct.getEighthStripBit());
575  thisLCT.setRun3Pattern(clct.getRun3Pattern());
576  }
577 }
578 
579 /* Construct LCT from CSC and GEM information. Option ALCT-2GEM */
581  const GEMInternalCluster& gem,
582  int trackNumber,
583  CSCCorrelatedLCTDigi& thisLCT) const {
584  thisLCT.setValid(true);
586  thisLCT.setQuality(qualityAssignment_->findQuality(alct, gem));
587  thisLCT.setALCT(getBXShiftedALCT(alct));
588  thisLCT.setGEM1(gem.mid1());
589  thisLCT.setGEM2(gem.mid2());
590  thisLCT.setPattern(10);
591  thisLCT.setMPCLink(0);
592  thisLCT.setBX0(0);
593  thisLCT.setSyncErr(0);
594  thisLCT.setCSCID(theTrigChamber);
595  thisLCT.setTrknmb(trackNumber);
596  thisLCT.setWireGroup(alct.getKeyWG());
597  thisLCT.setStrip(gem.getKeyStrip());
598  thisLCT.setBend(0);
599  thisLCT.setBX(alct.getBX());
600  if (runCCLUT_) {
601  thisLCT.setRun3(true);
602  thisLCT.setSlope(0);
603  thisLCT.setQuartStripBit(false);
604  thisLCT.setEighthStripBit(false);
605  // ALCT-2GEM type LCTs do not bend in the chamber
606  thisLCT.setRun3Pattern(4);
607  }
608 }
609 
611  // clear alct if they are of low quality without matching GEM clusters
612  if (alct.getQuality() == 0 and !cluster.isValid() and drop_low_quality_alct_no_gems_)
613  alct.clear();
614 }
615 
617  // Here, we need to check which could be an ME1/a LCT
618  bool dropLQCLCTNoGEMs = drop_low_quality_clct_no_gems_;
620  dropLQCLCTNoGEMs = drop_low_quality_clct_no_gems_me1a_;
621 
622  // clear clct if they are of low quality without matching GEM clusters
623  if (clct.getQuality() <= 3 and !cluster.isValid() and dropLQCLCTNoGEMs)
624  clct.clear();
625 }
626 
627 void CSCGEMMotherboard::sortLCTsByBending(std::vector<CSCCorrelatedLCTDigi>& lcts) const {
628  /*
629  For Run-2 GEM-CSC trigger primitives, which we temporarily have
630  to integrate with the Run-2 EMTF during LS2, we sort by quality.
631  Larger quality means smaller bending
632  */
633  if (!runCCLUT_) {
634  std::sort(lcts.begin(), lcts.end(), [](const CSCCorrelatedLCTDigi& lct1, const CSCCorrelatedLCTDigi& lct2) -> bool {
635  return lct1.getQuality() > lct2.getQuality();
636  });
637  }
638 
639  /*
640  For Run-3 GEM-CSC trigger primitives, which we have
641  to integrate with the Run-3 EMTF, we sort by slope.
642  Smaller slope means smaller bending
643  */
644  else {
645  std::sort(lcts.begin(), lcts.end(), [](const CSCCorrelatedLCTDigi& lct1, const CSCCorrelatedLCTDigi& lct2) -> bool {
646  return lct1.getSlope() < lct2.getSlope();
647  });
648  }
649 }
GEMPadDigi mid1() const
void matchALCTCLCT(bool bunch_crossing_mask[CSCConstants::MAX_ALCT_TBINS])
uint16_t getRun3Pattern() const
return pattern
Definition: CSCCLCTDigi.h:68
uint16_t getSlope() const
return the slope
void correlateLCTsGEM(const CSCALCTDigi &bestALCT, const CSCALCTDigi &secondALCT, const CSCCLCTDigi &bestCLCT, const CSCCLCTDigi &secondCLCT, const GEMInternalClusters &clusters, CSCCorrelatedLCTDigi &lct1, CSCCorrelatedLCTDigi &lct2) const
uint16_t getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:46
LCTContainer allLCTs_
uint16_t getKeyStrip(int n=2) const
void setPattern(const uint16_t p)
set pattern
void setALCT(const CSCALCTDigi &alct)
std::unique_ptr< CSCGEMMatcher > cscGEMMatcher_
const CSCL1TPLookupTableME11ILT * lookupTableME11ILT_
void setGEM2(const GEMPadDigi &gem)
std::vector< CSCCLCTDigi > clctV
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
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::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
unsigned int match_trig_window_size
uint16_t getBend() const
Definition: CSCCLCTDigi.h:93
CSCALCTDigi getBXShiftedALCT(const CSCALCTDigi &) const
void setSlope(const uint16_t slope)
set the slope
CSCCLCTDigi getBXShiftedCLCT(const CSCCLCTDigi &) const
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:40
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
void setQuartStripBit(const bool quartStripBit)
set single quart strip bit
uint16_t getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:73
void clear()
clear this ALCT
Definition: CSCALCTDigi.cc:60
void sortLCTsByBending(std::vector< CSCCorrelatedLCTDigi > &lcts) const
void setEighthStripBit(const bool eighthStripBit)
set single eighth strip bit
void setBend(const uint16_t b)
set bend
std::unique_ptr< CSCCathodeLCTProcessor > clctProc
void constructLCTsGEM(const CSCALCTDigi &alct, const CSCCLCTDigi &clct, const GEMInternalCluster &gem, CSCCorrelatedLCTDigi &lct) const
bool drop_low_quality_clct_no_gems_me1a_
Log< level::Error, false > LogError
void setValid(const uint16_t v)
set valid
void copyValidToInValid(CSCALCTDigi &, CSCALCTDigi &, CSCCLCTDigi &, CSCCLCTDigi &) const
std::string theCSCName_
Definition: CSCBaseboard.h:90
void matchALCT2GEM(bool bunch_crossing_mask[CSCConstants::MAX_ALCT_TBINS])
#define LogTrace(id)
uint16_t getKeyStrip(const uint16_t n=2) const
Definition: CSCCLCTDigi.cc:107
void setMPCLink(const uint16_t &link)
Set mpc link number after MPC sorting.
const unsigned theTrigChamber
Definition: CSCBaseboard.h:46
void setWireGroup(const uint16_t wiregroup)
set wiregroup number
std::vector< int > preferred_bx_match_
bool match_earliest_clct_only_
unsigned max_delta_bx_clct_gem_
std::vector< CSCALCTDigi > alctV
bool getEighthStripBit() const
get single eighth strip bit
Definition: CSCCLCTDigi.h:114
std::vector< GEMInternalCluster > GEMInternalClusters
unsigned int encodePattern(const int clctPattern) const
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:50
void dropLowQualityALCTNoClusters(CSCALCTDigi &alct, const GEMInternalCluster &cluster) const
void setRun3Pattern(const uint16_t pattern)
set Run-3 pattern
unsigned theChamber
Definition: CSCBaseboard.h:49
void setBX0(const uint16_t b)
set bx0
GEMPadDigi mid2() const
void matchCLCT2GEM(bool bunch_crossing_mask[CSCConstants::MAX_ALCT_TBINS])
const CSCGeometry * cscGeometry_
Definition: CSCBaseboard.h:71
edm::ParameterSet tmbParams_
Definition: CSCBaseboard.h:78
void setCSCID(const uint16_t c)
set cscID
void setRun3(const bool isRun3)
uint16_t getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:67
void setBX(const uint16_t b)
set bx
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const unsigned theStation
Definition: CSCBaseboard.h:43
uint16_t getSlope() const
return the slope
Definition: CSCCLCTDigi.h:74
uint16_t getPattern() const
return pattern
Definition: CSCCLCTDigi.h:62
void matchALCTCLCTGEM(bool bunch_crossing_mask[CSCConstants::MAX_ALCT_TBINS])
uint16_t getQuality() const
return the Quality
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc, const GEMPadDigiClusterCollection *gemPads)
std::shared_ptr< GEMClusterProcessor > clusterProc_
unsigned max_delta_bx_alct_gem_
const CSCL1TPLookupTableME21ILT * lookupTableME21ILT_
std::unique_ptr< CSCAnodeLCTProcessor > alctProc
const CSCL1TPLookupTableCCLUT * lookupTableCCLUT_
void setStrip(const uint16_t s)
set strip
void encodeHighMultiplicityBits()
void clear()
clear this CLCT
Definition: CSCCLCTDigi.cc:73
void dropLowQualityCLCTNoClusters(CSCCLCTDigi &clct, const GEMInternalCluster &cluster) const
unsigned getKeyWG() const
uint16_t getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:56
CSCGEMMotherboard(unsigned endcap, unsigned station, unsigned sector, unsigned subsector, unsigned chamber, const edm::ParameterSet &conf)
void setQuality(const uint16_t q)
set quality code
Log< level::Warning, false > LogWarning
~CSCGEMMotherboard() override
const GEMGeometry * gem_g
bool isCoincidence() const
void setTrknmb(const uint16_t number)
Set track number (1,2) after sorting LCTs.
void setCLCT(const CSCCLCTDigi &clct)
void setGEM1(const GEMPadDigi &gem)
void setSyncErr(const uint16_t s)
set syncErr
bool getQuartStripBit() const
get single quart strip bit
Definition: CSCCLCTDigi.h:108
std::unique_ptr< LCTQualityAssignment > qualityAssignment_