CMS 3D CMS Logo

CSCMotherboardME11GEM.cc
Go to the documentation of this file.
9 
10 #include <cmath>
11 #include <tuple>
12 #include <set>
13 
14 // LUT for which ME1/1 wire group can cross which ME1/a halfstrip
15 // 1st index: WG number
16 // 2nd index: inclusive HS range
18 {0, 95},{0, 95},{0, 95},{0, 95},{0, 95},
19 {0, 95},{0, 95},{0, 95},{0, 95},{0, 95},
20 {0, 95},{0, 95},{0, 77},{0, 61},{0, 39},
21 {0, 22},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
22 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
23 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
24 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
25 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
26 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
27 {-1,-1},{-1,-1},{-1,-1} };
28 // a modified LUT for ganged ME1a
30 {0, 31},{0, 31},{0, 31},{0, 31},{0, 31},
31 {0, 31},{0, 31},{0, 31},{0, 31},{0, 31},
32 {0, 31},{0, 31},{0, 31},{0, 31},{0, 31},
33 {0, 22},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
34 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
35 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
36 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
37 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
38 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
39 {-1,-1},{-1,-1},{-1,-1} };
40 
41 // LUT for which ME1/1 wire group can cross which ME1/b halfstrip
42 // 1st index: WG number
43 // 2nd index: inclusive HS range
45 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
46 {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
47 {100, 127},{73, 127},{47, 127},{22, 127},{0, 127},
48 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
49 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
50 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
51 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
52 {0, 127},{0, 127},{0, 127},{0, 127},{0, 127},
53 {0, 127},{0, 127},{0, 127},{0, 127},{0, 105},
54 {0, 93},{0, 78},{0, 63} };
55 
56 // LUT with bending angles of the GEM-CSC high efficiency patterns (98%)
57 // 1st index: pt value = {3,5,7,10,15,20,30,40}
58 // 2nd index: bending angle for odd numbered chambers
59 // 3rd index: bending angle for even numbered chambers
61  {3, 0.03971647, 0.01710244},
62  {5, 0.02123785, 0.00928431},
63  {7, 0.01475524, 0.00650928},
64  {10, 0.01023299, 0.00458796},
65  {15, 0.00689220, 0.00331313},
66  {20, 0.00535176, 0.00276152},
67  {30, 0.00389050, 0.00224959},
68  {40, 0.00329539, 0.00204670}};
69 
71 {0, 2.44005, 2.44688},
72 {1, 2.38863, 2.45035},
73 {2, 2.32742, 2.43077},
74 {3, 2.30064, 2.40389},
75 {4, 2.2746, 2.37775},
76 {5, 2.24925, 2.35231},
77 {6, 2.22458, 2.32754},
78 {7, 2.20054, 2.30339},
79 {8, 2.1771, 2.27985},
80 {9, 2.15425, 2.25689},
81 {10, 2.13194, 2.23447},
82 {11, 2.11016, 2.21258},
83 {12, 2.08889, 2.19119},
84 {13, 2.06809, 2.17028},
85 {14, 2.04777, 2.14984},
86 {15, 2.02788, 2.12983},
87 {16, 2.00843, 2.11025},
88 {17, 1.98938, 2.09108},
89 {18, 1.97073, 2.0723},
90 {19, 1.95246, 2.0539},
91 {20, 1.93456, 2.03587},
92 {21, 1.91701, 2.01818},
93 {22, 1.8998, 2.00084},
94 {23, 1.88293, 1.98382},
95 {24, 1.86637, 1.96712},
96 {25, 1.85012, 1.95073},
97 {26, 1.83417, 1.93463},
98 {27, 1.8185, 1.91882},
99 {28, 1.80312, 1.90329},
100 {29, 1.788, 1.88803},
101 {30, 1.77315, 1.87302},
102 {31, 1.75855, 1.85827},
103 {32, 1.74421, 1.84377},
104 {33, 1.7301, 1.8295},
105 {34, 1.71622, 1.81547},
106 {35, 1.70257, 1.80166},
107 {36, 1.68914, 1.78807},
108 {37, 1.67592, 1.77469},
109 {38, 1.66292, 1.76151},
110 {39, 1.65011, 1.74854},
111 {40, 1.63751, 1.73577},
112 {41, 1.62509, 1.72319},
113 {42, 1.61287, 1.71079},
114 {43, 1.60082, 1.69857},
115 {44, 1.59924, 1.68654},
116 {45, 1.6006, 1.67467},
117 {46, 1.60151, 1.66297},
118 {47, 1.60198, 1.65144} };
119 
121 {0, 2.3917, 2.39853},
122 {1, 2.34037, 2.40199},
123 {2, 2.27928, 2.38244},
124 {3, 2.25254, 2.35561},
125 {4, 2.22655, 2.32951},
126 {5, 2.20127, 2.30412},
127 {6, 2.17665, 2.27939},
128 {7, 2.15267, 2.25529},
129 {8, 2.12929, 2.2318},
130 {9, 2.1065, 2.20889},
131 {10, 2.08425, 2.18652},
132 {11, 2.06253, 2.16468},
133 {12, 2.04132, 2.14334},
134 {13, 2.0206, 2.12249},
135 {14, 2.00033, 2.1021},
136 {15, 1.98052, 2.08215},
137 {16, 1.96113, 2.06262},
138 {17, 1.94215, 2.04351},
139 {18, 1.92357, 2.02479},
140 {19, 1.90538, 2.00645},
141 {20, 1.88755, 1.98847},
142 {21, 1.87007, 1.97085},
143 {22, 1.85294, 1.95357},
144 {23, 1.83614, 1.93662},
145 {24, 1.81965, 1.91998},
146 {25, 1.80348, 1.90365},
147 {26, 1.78761, 1.88762},
148 {27, 1.77202, 1.87187},
149 {28, 1.75672, 1.85641},
150 {29, 1.74168, 1.84121},
151 {30, 1.72691, 1.82628},
152 {31, 1.7124, 1.8116},
153 {32, 1.69813, 1.79716},
154 {33, 1.68411, 1.78297},
155 {34, 1.67032, 1.769},
156 {35, 1.65675, 1.75526},
157 {36, 1.64341, 1.74174},
158 {37, 1.63028, 1.72844},
159 {38, 1.61736, 1.71534},
160 {39, 1.60465, 1.70245},
161 {40, 1.59213, 1.68975},
162 {41, 1.57981, 1.67724},
163 {42, 1.56767, 1.66492},
164 {43, 1.55572, 1.65278},
165 {44, 1.55414, 1.64082},
166 {45, 1.55549, 1.62903},
167 {46, 1.5564, 1.61742},
168 {47, 1.55686, 1.60596} };
169 
171  unsigned sector, unsigned subsector,
172  unsigned chamber,
173  const edm::ParameterSet& conf) :
174  CSCMotherboard(endcap, station, sector, subsector, chamber, conf)
175 {
176  const edm::ParameterSet commonParams(conf.getParameter<edm::ParameterSet>("commonParam"));
177 
178  // special configuration parameters for ME11 treatment
179  smartME1aME1b = commonParams.getParameter<bool>("smartME1aME1b");
180  disableME1a = commonParams.getParameter<bool>("disableME1a");
181  gangedME1a = commonParams.getParameter<bool>("gangedME1a");
182  runME11ILT_ = commonParams.getParameter<bool>("runME11ILT");
183 
184  if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError")
185  << "+++ Upgrade CSCMotherboardME11GEM constructed while isSLHC is not set! +++\n";
186  if (!smartME1aME1b) edm::LogError("L1CSCTPEmulatorConfigError")
187  << "+++ Upgrade CSCMotherboardME11GEM constructed while smartME1aME1b is not set! +++\n";
188 
189  const edm::ParameterSet alctParams(conf.getParameter<edm::ParameterSet>("alctSLHC"));
190  const edm::ParameterSet clctParams(conf.getParameter<edm::ParameterSet>("clctSLHC"));
191  const edm::ParameterSet me11tmbParams(conf.getParameter<edm::ParameterSet>("me11tmbSLHCGEM"));
192  const edm::ParameterSet coPadParams(conf.getParameter<edm::ParameterSet>("copadParam"));
193 
194  clct1a.reset( new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, me11tmbParams) );
195  clct1a->setRing(4);
197  coPadProcessor.reset( new GEMCoPadProcessor(endcap, station, gemChamber, coPadParams) );
198  match_earliest_alct_me11_only = me11tmbParams.getParameter<bool>("matchEarliestAlctME11Only");
199  match_earliest_clct_me11_only = me11tmbParams.getParameter<bool>("matchEarliestClctME11Only");
200 
201  // if true: use regular CLCT-to-ALCT matching in TMB
202  // if false: do ALCT-to-CLCT matching
203  clct_to_alct = me11tmbParams.getParameter<bool>("clctToAlct");
204 
205  // whether to not reuse CLCTs that were used by previous matching ALCTs
206  // in ALCT-to-CLCT algorithm
207  drop_used_clcts = me11tmbParams.getParameter<bool>("tmbDropUsedClcts");
208 
209  tmb_cross_bx_algo = me11tmbParams.getParameter<unsigned int>("tmbCrossBxAlgorithm");
210 
211  // maximum lcts per BX in ME11: 2, 3, 4 or 999
212  max_me11_lcts = me11tmbParams.getParameter<unsigned int>("maxME11LCTs");
213 
215  for (unsigned int m=2; m<match_trig_window_size; m+=2)
216  {
217  pref[m-1] = pref[0] - m/2;
218  pref[m] = pref[0] + m/2;
219  }
220 
221  //----------------------------------------------------------------------------------------//
222 
223  // G E M - C S C I N T E G R A T E D L O C A L A L G O R I T H M
224 
225  //----------------------------------------------------------------------------------------//
226 
227  // debug gem matching
228  debug_gem_matching = me11tmbParams.getParameter<bool>("debugMatching");
229  debug_luts = me11tmbParams.getParameter<bool>("debugLUTs");
230 
231  // deltas used to match to GEM pads
232  maxDeltaBXPadEven_ = me11tmbParams.getParameter<int>("maxDeltaBXPadEven");
233  maxDeltaPadPadEven_ = me11tmbParams.getParameter<int>("maxDeltaPadPadEven");
234  maxDeltaBXPadOdd_ = me11tmbParams.getParameter<int>("maxDeltaBXPadOdd");
235  maxDeltaPadPadOdd_ = me11tmbParams.getParameter<int>("maxDeltaPadPadOdd");
236 
237  // deltas used to match to GEM coincidence pads
238  maxDeltaBXCoPadEven_ = me11tmbParams.getParameter<int>("maxDeltaBXCoPadEven");
239  maxDeltaPadCoPadEven_ = me11tmbParams.getParameter<int>("maxDeltaPadCoPadEven");
240  maxDeltaBXCoPadOdd_ = me11tmbParams.getParameter<int>("maxDeltaBXCoPadOdd");
241  maxDeltaPadCoPadOdd_ = me11tmbParams.getParameter<int>("maxDeltaPadCoPadOdd");
242 
243  // drop low quality stubs if they don't have GEMs
244  dropLowQualityCLCTsNoGEMs_ME1a_ = me11tmbParams.getParameter<bool>("dropLowQualityCLCTsNoGEMs_ME1a");
245  dropLowQualityCLCTsNoGEMs_ME1b_ = me11tmbParams.getParameter<bool>("dropLowQualityCLCTsNoGEMs_ME1b");
246  dropLowQualityALCTsNoGEMs_ME1a_ = me11tmbParams.getParameter<bool>("dropLowQualityALCTsNoGEMs_ME1a");
247  dropLowQualityALCTsNoGEMs_ME1b_ = me11tmbParams.getParameter<bool>("dropLowQualityALCTsNoGEMs_ME1b");
248 
249  // build LCT from ALCT and GEM
250  buildLCTfromALCTandGEM_ME1a_ = me11tmbParams.getParameter<bool>("buildLCTfromALCTandGEM_ME1a");
251  buildLCTfromALCTandGEM_ME1b_ = me11tmbParams.getParameter<bool>("buildLCTfromALCTandGEM_ME1b");
252  buildLCTfromCLCTandGEM_ME1a_ = me11tmbParams.getParameter<bool>("buildLCTfromCLCTandGEM_ME1a");
253  buildLCTfromCLCTandGEM_ME1b_ = me11tmbParams.getParameter<bool>("buildLCTfromCLCTandGEM_ME1b");
254 
255  // LCT ghostbusting
256  doLCTGhostBustingWithGEMs_ = me11tmbParams.getParameter<bool>("doLCTGhostBustingWithGEMs");
257 
258  // correct LCT timing with GEMs
259  correctLCTtimingWithGEM_ = me11tmbParams.getParameter<bool>("correctLCTtimingWithGEM");
260 
261  // use "old" or "new" dataformat for integrated LCTs?
262  useOldLCTDataFormat_ = me11tmbParams.getParameter<bool>("useOldLCTDataFormat");
263 
264  // promote ALCT-GEM pattern
265  promoteALCTGEMpattern_ = me11tmbParams.getParameter<bool>("promoteALCTGEMpattern");
266 
267  // promote ALCT-GEM quality
268  promoteALCTGEMquality_ = me11tmbParams.getParameter<bool>("promoteALCTGEMquality");
269  promoteCLCTGEMquality_ME1a_ = me11tmbParams.getParameter<bool>("promoteCLCTGEMquality_ME1a");
270  promoteCLCTGEMquality_ME1b_ = me11tmbParams.getParameter<bool>("promoteCLCTGEMquality_ME1b");
271 }
272 
273 
275 {
276  // Constructor used only for testing.
277 
278  clct1a.reset( new CSCCathodeLCTProcessor() );
279  clct1a->setRing(4);
280 
282  for (unsigned int m=2; m<match_trig_window_size; m+=2)
283  {
284  pref[m-1] = pref[0] - m/2;
285  pref[m] = pref[0] + m/2;
286  }
287 }
288 
289 
291 {
292 }
293 
294 
296 {
298  if (clct1a) clct1a->clear();
299  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
300  {
301  //firstLCT1a[bx].clear();
302  //secondLCT1a[bx].clear();
303  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
304  for (int i=0;i<2;i++)
305  {
306  allLCTs1b[bx][mbx][i].clear();
307  allLCTs1a[bx][mbx][i].clear();
308  }
309  }
310  gemRollToEtaLimits_.clear();
311  cscWgToGemRoll_.clear();
312 
313  gemPadToCscHsME1a_.clear();
314  gemPadToCscHsME1b_.clear();
315 
316  cscHsToGemPadME1a_.clear();
317  cscHsToGemPadME1b_.clear();
318 
319  pads_.clear();
320  coPads_.clear();
321 }
322 
323 // Set configuration parameters obtained via EventSetup mechanism.
325 {
326  alct->setConfigParameters(conf);
327  clct->setConfigParameters(conf);
328  clct1a->setConfigParameters(conf);
329  // No config. parameters in DB for the TMB itself yet.
330 }
331 
332 
334  const CSCComparatorDigiCollection* compdc,
335  const GEMPadDigiCollection* gemPads)
336 {
337  clear();
338 
339  if (!( alct and clct and clct1a and smartME1aME1b))
340  {
341  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
342  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
343  return;
344  }
345 
346  alctV = alct->run(wiredc); // run anodeLCT
347  clctV1b = clct->run(compdc); // run cathodeLCT in ME1/b
348  clctV1a = clct1a->run(compdc); // run cathodeLCT in ME1/a
349 
350  // if there are no ALCTs and no CLCTs, it does not make sense to run this TMB
351  if (alctV.empty() and (clctV1b.empty() or clctV1a.empty())) return;
352 
353  gemCoPadV = coPadProcessor->run(gemPads); // run copad processor in GE1/1
354 
355  bool gemGeometryAvailable(false);
356  if (gem_g != nullptr) {
357  if (infoV >= 0) edm::LogInfo("L1CSCTPEmulatorSetupInfo")
358  << "+++ run() called for GEM-CSC integrated trigger! +++ \n";
359  gemGeometryAvailable = true;
360  }
361 
362  int used_clct_mask[20], used_clct_mask_1a[20];
363  for (int b=0;b<20;b++)
364  used_clct_mask[b] = used_clct_mask_1a[b] = 0;
365 
366  // retrieve CSCChamber geometry
368  const CSCChamber* cscChamberME1b(geo_manager->chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber));
369  const CSCDetId me1bId(cscChamberME1b->id());
370  const CSCDetId me1aId(me1bId.endcap(), 1, 4, me1bId.chamber());
371  const CSCChamber* cscChamberME1a(csc_g->chamber(me1aId));
372 
373  const int region((theEndcap == 1) ? 1: -1);
374  const GEMDetId gem_id(region, 1, theStation, 1, me1bId.chamber(), 0);
375  const GEMChamber* gemChamber(gem_g->chamber(gem_id));
376  // check if the GEM chamber is really there
377  if (!gemChamber) runME11ILT_ = false;
378 
379  if (runME11ILT_){
380 
381  // check for GEM geometry
382  if (not gemGeometryAvailable){
383  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
384  << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n";
385  return;
386  }
387 
388  // trigger geometry
389  const CSCLayer* keyLayerME1b(cscChamberME1b->layer(3));
390  const CSCLayerGeometry* keyLayerGeometryME1b(keyLayerME1b->geometry());
391  const CSCLayer* keyLayerME1a(cscChamberME1a->layer(3));
392  const CSCLayerGeometry* keyLayerGeometryME1a(keyLayerME1a->geometry());
393 
394  const bool isEven(me1bId.chamber()%2==0);
395  const int region((theEndcap == 1) ? 1: -1);
396  const GEMDetId gem_id(region, 1, theStation, 0, me1bId.chamber(), 0);
397  const GEMSuperChamber* gemChamber(gem_g->superChamber(gem_id));
398 
399  // initialize depending on whether even or odd
404 
405  // LUT<roll,<etaMin,etaMax> >
406  createGEMRollEtaLUT(isEven);
407  if (debug_luts){
408  LogDebug("CSCMotherboardME11GEM") << "me1b Det "<< me1bId<<" "<< me1bId.rawId() <<" "
409  << (isEven ? "Even":"odd") <<" chamber "<< me1bId.chamber()<<std::endl;
410  for (const auto& p : gemRollToEtaLimits_)
411  LogDebug("CSCMotherboardME11GEM") << "pad "<< p.first << " min eta " << (p.second).first << " max eta " << (p.second).second << std::endl;
412  }
413 
414  // loop on all wiregroups to create a LUT <WG,rollMin,rollMax>
415  const int numberOfWG(keyLayerGeometryME1b->numberOfWireGroups());
416  for (int i = 0; i< numberOfWG; ++i){
418  auto etaMax(isEven ? lut_wg_etaMin_etaMax_even[i][2] : lut_wg_etaMin_etaMax_odd[i][2]);
420  }
421  if (debug_luts){
422  for (const auto& p : cscWgToGemRoll_) {
423  LogDebug("CSCMotherboardME11GEM") << "WG "<< p.first << " GEM pads " << (p.second).first << " " << (p.second).second << std::endl;
424  }
425  }
426 
427  // pick any roll
428  const auto& randRoll(gemChamber->chamber(1)->etaPartition(2));
429 
430  const int nGEMPads(randRoll->npads());
431  for (int i = 1; i<= nGEMPads; ++i){
432  const LocalPoint& lpGEM(randRoll->centreOfPad(i));
433  const GlobalPoint& gp(randRoll->toGlobal(lpGEM));
434  const LocalPoint& lpCSCME1a(keyLayerME1a->toLocal(gp));
435  const LocalPoint& lpCSCME1b(keyLayerME1b->toLocal(gp));
436  const float stripME1a(keyLayerGeometryME1a->strip(lpCSCME1a));
437  const float stripME1b(keyLayerGeometryME1b->strip(lpCSCME1b));
438  // HS are wrapped-around
439  gemPadToCscHsME1a_[i] = (int) (stripME1a*2);
440  gemPadToCscHsME1b_[i] = (int) (stripME1b*2);
441  }
442  if (debug_luts){
443  LogDebug("CSCMotherboardME11GEM") << "detId " << me1bId;
444  LogDebug("CSCMotherboardME11GEM") << "CSCHSToGEMPad LUT in ME1a";
445  for (const auto& p : cscHsToGemPadME1a_) {
446  LogDebug("CSCMotherboardME11GEM") << "CSC HS "<< p.first << " GEM Pad low " << (p.second).first << " GEM Pad high " << (p.second).second;
447  }
448  LogDebug("CSCMotherboardME11GEM") << "CSCHSToGEMPad LUT in ME1b";
449  for (const auto& p : cscHsToGemPadME1b_) {
450  LogDebug("CSCMotherboardME11GEM") << "CSC HS "<< p.first << " GEM Pad low " << (p.second).first << " GEM Pad high " << (p.second).second;
451  }
452  }
453 
454  auto nStripsME1a(keyLayerGeometryME1a->numberOfStrips());
455  auto nStripsME1b(keyLayerGeometryME1b->numberOfStrips());
456 
457  // The code below does the reverse mapping namely CSC strip to GEM pad
458  // The old code (mapping GEM onto CSC directly) was not functioning
459  // as expected, so I temporarily modifie it. In addition I have to manually
460  // insert some numbers. This code will be cleaned up in the future.
461  for (int i=0; i<nStripsME1a*2; ++i){
462  std::vector<int> temp;
463  for (auto& p: gemPadToCscHsME1a_){
464  if (p.second == i) {
465  temp.push_back(p.first);
466  }
467  }
468  // get unique values
469  std::sort(temp.begin(),temp.end());
470  temp.erase(std::unique(temp.begin(),temp.end()),temp.end());
471  // keep only the middle two or middle element
472  std::set<int> temp2;
473  if (temp.size()%2==0 and !temp.empty()){
474  // pick middle two
475  temp2.insert(temp[temp.size()/2]);
476  temp2.insert(temp[temp.size()/2-1]);
477  }
478  else if (temp.size()%2==1){
479  // pick middle
480  temp2.insert(temp[temp.size()/2]);
481  }
482  else if (temp.empty()) {
483  temp2.insert(-99);
484  }
485  cscHsToGemPadME1a_[i] = std::make_pair(*temp2.begin(), *temp2.rbegin());
486  // special cases
487  if (isEven){
488  cscHsToGemPadME1a_[0] = std::make_pair(1,1);
489  cscHsToGemPadME1a_[1] = std::make_pair(1,1);
490  cscHsToGemPadME1a_[94] = std::make_pair(192,192);
491  cscHsToGemPadME1a_[95] = std::make_pair(192,192);
492  } else {
493  cscHsToGemPadME1a_[0] = std::make_pair(192,192);
494  cscHsToGemPadME1a_[1] = std::make_pair(192,192);
495  cscHsToGemPadME1a_[94] = std::make_pair(1,1);
496  cscHsToGemPadME1a_[95] = std::make_pair(1,1);
497  }
498  }
499 
500  for (int i=0; i<nStripsME1b*2; ++i){
501  std::vector<int> temp;
502  for (auto& p: gemPadToCscHsME1b_){
503  if (p.second == i) {
504  temp.push_back(p.first);
505  }
506  }
507  // get unique values
508  std::sort(temp.begin(),temp.end());
509  temp.erase(std::unique(temp.begin(),temp.end()),temp.end());
510  // keep only the middle two or middle element
511  std::set<int> temp2;
512  if (temp.size()%2==0 and !temp.empty()){
513  // pick middle two
514  temp2.insert(temp[temp.size()/2]);
515  temp2.insert(temp[temp.size()/2-1]);
516  }
517  else if (temp.size()%2==1){
518  // pick middle
519  temp2.insert(temp[temp.size()/2]);
520  }
521 
522  if (temp.empty()) {
523  temp2.insert(-99);
524  }
525  cscHsToGemPadME1b_[i] = std::make_pair(*temp2.begin(), *temp2.rbegin());
526  // special cases
527  if (isEven){
528  cscHsToGemPadME1b_[0] = std::make_pair(1,1);
529  cscHsToGemPadME1b_[1] = std::make_pair(1,1);
530  cscHsToGemPadME1b_[2] = std::make_pair(1,1);
531  cscHsToGemPadME1b_[3] = std::make_pair(1,1);
532  cscHsToGemPadME1b_[124] = std::make_pair(192,192);
533  cscHsToGemPadME1b_[125] = std::make_pair(192,192);
534  cscHsToGemPadME1b_[126] = std::make_pair(192,192);
535  cscHsToGemPadME1b_[127] = std::make_pair(192,192);
536  } else {
537  cscHsToGemPadME1b_[0] = std::make_pair(192,192);
538  cscHsToGemPadME1b_[1] = std::make_pair(192,192);
539  cscHsToGemPadME1b_[2] = std::make_pair(192,192);
540  cscHsToGemPadME1b_[3] = std::make_pair(192,192);
541  cscHsToGemPadME1b_[124] = std::make_pair(1,1);
542  cscHsToGemPadME1b_[125] = std::make_pair(1,1);
543  cscHsToGemPadME1b_[126] = std::make_pair(1,1);
544  cscHsToGemPadME1b_[127] = std::make_pair(1,1);
545  }
546  }
547 
548  if (debug_luts){
549  LogDebug("CSCMotherboardME11GEM") << "detId " << me1bId;
550  LogDebug("CSCMotherboardME11GEM") << "GEMPadToCSCHs LUT in ME1a";
551  for (const auto& p : gemPadToCscHsME1a_) {
552  LogDebug("CSCMotherboardME11GEM") << "GEM Pad "<< p.first << " CSC HS: " << p.second;
553  }
554  LogDebug("CSCMotherboardME11GEM") << "GEMPadToCSCHs LUT in ME1b";
555  for (const auto& p : gemPadToCscHsME1b_) {
556  LogDebug("CSCMotherboardME11GEM") << "GEM Pad "<< p.first << " CSC HS: " << p.second;
557  }
558  }
559 
560  // retrieve pads and copads in a certain BX window for this CSC
561  pads_.clear();
562  coPads_.clear();
563  retrieveGEMPads(gemPads, gem_id);
565  }
566 
567  const bool hasPads(!pads_.empty());
568  bool hasLCTs(false);
569 
570  // ALCT-centric matching
571  for (int bx_alct = 0; bx_alct < CSCAnodeLCTProcessor::MAX_ALCT_BINS; bx_alct++)
572  {
573  if (alct->bestALCT[bx_alct].isValid())
574  {
575  const int bx_clct_start(bx_alct - match_trig_window_size/2);
576  const int bx_clct_stop(bx_alct + match_trig_window_size/2);
577  const int bx_copad_start(bx_alct - maxDeltaBXCoPad_);
578  const int bx_copad_stop(bx_alct + maxDeltaBXCoPad_);
579 
580  if (debug_gem_matching){
581  std::cout << "========================================================================" << std::endl;
582  std::cout << "ALCT-CLCT matching in ME1/1 chamber: " << cscChamberME1b->id() << std::endl;
583  std::cout << "------------------------------------------------------------------------" << std::endl;
584  std::cout << "+++ Best ALCT Details: " << alct->bestALCT[bx_alct] << std::endl;
585  if (not alct->secondALCT[bx_alct].isValid())
586  std::cout << "+++ Second ALCT INVALID" << std::endl;
587  else
588  std::cout << "+++ Second ALCT Details: " << alct->secondALCT[bx_alct] << std::endl;
589 
590  printGEMTriggerPads(bx_clct_start, bx_clct_stop);
591  printGEMTriggerPads(bx_clct_start, bx_clct_stop, true);
592 
593  std::cout << "------------------------------------------------------------------------" << std::endl;
594  std::cout << "Attempt ALCT-CLCT matching in ME1/b in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl;
595  }
596 
597  // ALCT-to-CLCT matching in ME1b
598  int nSuccesFulMatches = 0;
599  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
600  {
601  if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
602  if (drop_used_clcts and used_clct_mask[bx_clct]) continue;
603  if (clct->bestCLCT[bx_clct].isValid())
604  {
605  const int quality(clct->bestCLCT[bx_clct].getQuality());
606  if (debug_gem_matching) std::cout << "++Valid ME1b CLCT: " << clct->bestCLCT[bx_clct] << std::endl;
607 
608  // pick the pad that corresponds
609  const auto& matchingPads11(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_alct], ME1B, false));
610  const auto& matchingPads12(matchingGEMPads(clct->bestCLCT[bx_clct], alct->secondALCT[bx_alct], pads_[bx_alct], ME1B, false));
611  const auto& matchingPads21(matchingGEMPads(clct->secondCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_alct], ME1B, false));
612  const auto& matchingPads22(matchingGEMPads(clct->secondCLCT[bx_clct], alct->secondALCT[bx_alct], pads_[bx_alct], ME1B, false));
613  GEMPadsBX matchingPads;
614  matchingPads.reserve(matchingPads11.size() +
615  matchingPads12.size() +
616  matchingPads21.size() +
617  matchingPads22.size()
618  );
619  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads11), std::end(matchingPads11));
620  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads12), std::end(matchingPads12));
621  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads21), std::end(matchingPads21));
622  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads22), std::end(matchingPads22));
623 
624  const auto& matchingCoPads11(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_alct], ME1B, false));
625  const auto& matchingCoPads12(matchingGEMPads(clct->bestCLCT[bx_clct], alct->secondALCT[bx_alct], coPads_[bx_alct], ME1B, false));
626  const auto& matchingCoPads21(matchingGEMPads(clct->secondCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_alct], ME1B, false));
627  const auto& matchingCoPads22(matchingGEMPads(clct->secondCLCT[bx_clct], alct->secondALCT[bx_alct], coPads_[bx_alct], ME1B, false));
628  GEMPadsBX matchingCoPads;
629  matchingCoPads.reserve(matchingCoPads11.size() +
630  matchingCoPads12.size() +
631  matchingCoPads21.size() +
632  matchingCoPads22.size()
633  );
634  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads11), std::end(matchingCoPads11));
635  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads12), std::end(matchingCoPads12));
636  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads21), std::end(matchingCoPads21));
637  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads22), std::end(matchingCoPads22));
638 
639  if (runME11ILT_ and dropLowQualityCLCTsNoGEMs_ME1b_ and quality < 4 and hasPads){
640  int nFound(!matchingPads.empty());
641  const bool clctInEdge(clct->bestCLCT[bx_clct].getKeyStrip() < 5 or clct->bestCLCT[bx_clct].getKeyStrip() > 124);
642  if (clctInEdge){
643  if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT in CSC chamber edge, don't care about GEM pads" << std::endl;
644  }
645  else {
646  if (nFound != 0){
647  if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT with " << nFound << " matching GEM trigger pads" << std::endl;
648  }
649  else {
650  if (debug_gem_matching) std::cout << "\tWarning: low quality CLCT without matching GEM trigger pad" << std::endl;
651  continue;
652  }
653  }
654  }
655 
656  // check timing
658  int nFound(!matchingCoPads.empty());
659  if (nFound != 0 and bx_alct == 6 and bx_clct != 6){
660  if (debug_gem_matching) std::cout << "\tInfo: CLCT with incorrect timing" << std::endl;
661  continue;
662  }
663  }
664 
665  ++nSuccesFulMatches;
666 
667  hasLCTs = true;
668  // if (infoV > 1) LogTrace("CSCMotherboard")
669  int mbx = bx_clct-bx_clct_start;
670  correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
671  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
672  allLCTs1b[bx_alct][mbx][0], allLCTs1b[bx_alct][mbx][1], ME1B, matchingPads, matchingCoPads);
673  if (debug_gem_matching) {
674  std::cout << "Successful ALCT-CLCT match in ME1b: bx_alct = " << bx_alct
675  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
676  << "]; bx_clct = " << bx_clct << std::endl;
677  std::cout << "+++ Best CLCT Details: " << clct->bestCLCT[bx_clct] << std::endl;
678  if (not clct->secondCLCT[bx_clct].isValid())
679  std::cout << "+++ Second CLCT INVALID" << std::endl;
680  else
681  std::cout << "+++ Second CLCT Details: " << clct->secondCLCT[bx_clct] << std:: endl;
682  }
683 
684  if (allLCTs1b[bx_alct][mbx][0].isValid()) {
685  used_clct_mask[bx_clct] += 1;
687  }
688  }
689  }
690 
691  if (nSuccesFulMatches==0)
692  if (debug_gem_matching) std::cout << "++No valid ALCT-CLCT matches in ME1b" << std::endl;
693 
694  // ALCT-to-GEM matching in ME1b
695  int nSuccesFulGEMMatches = 0;
696  if (runME11ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandGEM_ME1b_){
697  for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) {
698 
699  if (debug_gem_matching) std::cout <<"ALCT-to-GEM matching in ME1b, bx_gem "<< bx_gem << std::endl;
700  // find the best matching copad
701  const auto& copads1(matchingGEMPads(alct->bestALCT[bx_alct], coPads_[bx_gem], ME1B, false));
702  const auto& copads2(matchingGEMPads(alct->secondALCT[bx_alct], coPads_[bx_gem], ME1B, false));
703  GEMPadsBX copads;
704  copads.reserve(copads1.size() +
705  copads2.size()
706  );
707  copads.insert(std::end(copads), std::begin(copads1), std::end(copads1));
708  copads.insert(std::end(copads), std::begin(copads2), std::end(copads2));
709 
710  if (debug_gem_matching) std::cout << "\t++Number of matching GEM CoPads in BX " << bx_alct << " : "<< copads.size() << std::endl;
711  if (copads.empty()) {
712  continue;
713  }
714 
715  correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
716  copads.at(0).second, allLCTs1b[bx_alct][0][0], allLCTs1b[bx_alct][0][1], ME1B);
717  if (allLCTs1b[bx_alct][0][0].isValid()) {
718  ++nSuccesFulGEMMatches;
720  }
721  if (debug_gem_matching) {
722  std::cout << "Successful ALCT-GEM CoPad match in ME1b: bx_alct = " << bx_alct << std::endl << std::endl;
723  std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
724  }
725  }
726  }
727 
728  if (debug_gem_matching) {
729  std::cout << "========================================================================" << std::endl;
730  std::cout << "Summary: " << std::endl;
731  if (nSuccesFulMatches>1)
732  std::cout << "Too many successful ALCT-CLCT matches in ME1b: " << nSuccesFulMatches
733  << ", CSCDetId " << cscChamberME1b->id()
734  << ", bx_alct = " << bx_alct
735  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
736  else if (nSuccesFulMatches==1)
737  std::cout << "1 successful ALCT-CLCT match in ME1b: "
738  << " CSCDetId " << cscChamberME1b->id()
739  << ", bx_alct = " << bx_alct
740  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
741  else if (nSuccesFulGEMMatches==1)
742  std::cout << "1 successful ALCT-GEM match in ME1b: "
743  << " CSCDetId " << cscChamberME1b->id()
744  << ", bx_alct = " << bx_alct
745  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
746  else
747  std::cout << "Unsuccessful ALCT-CLCT match in ME1b: "
748  << "CSCDetId " << cscChamberME1b->id()
749  << ", bx_alct = " << bx_alct
750  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
751 
752  std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
753  std::cout << "Attempt ALCT-CLCT matching in ME1/a in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl;
754  }
755 
756  // ALCT-to-CLCT matching in ME1a
757  nSuccesFulMatches = 0;
758  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
759  {
760  if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
761  if (drop_used_clcts and used_clct_mask_1a[bx_clct]) continue;
762  if (clct1a->bestCLCT[bx_clct].isValid())
763  {
764  const int quality(clct1a->bestCLCT[bx_clct].getQuality());
765  if (debug_gem_matching) std::cout << "++Valid ME1a CLCT: " << clct1a->bestCLCT[bx_clct] << std::endl;
766 
767  // pick the pad that corresponds
768  const auto& matchingPads11(matchingGEMPads(clct1a->bestCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_alct], ME1A, false));
769  const auto& matchingPads12(matchingGEMPads(clct1a->bestCLCT[bx_clct], alct->secondALCT[bx_alct], pads_[bx_alct], ME1A, false));
770  const auto& matchingPads21(matchingGEMPads(clct1a->secondCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_alct], ME1A, false));
771  const auto& matchingPads22(matchingGEMPads(clct1a->secondCLCT[bx_clct], alct->secondALCT[bx_alct], pads_[bx_alct], ME1A, false));
772  GEMPadsBX matchingPads;
773  matchingPads.reserve(matchingPads11.size() +
774  matchingPads12.size() +
775  matchingPads21.size() +
776  matchingPads22.size()
777  );
778  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads11), std::end(matchingPads11));
779  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads12), std::end(matchingPads12));
780  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads21), std::end(matchingPads21));
781  matchingPads.insert(std::end(matchingPads), std::begin(matchingPads22), std::end(matchingPads22));
782 
783  const auto& matchingCoPads11(matchingGEMPads(clct1a->bestCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_alct], ME1A, false));
784  const auto& matchingCoPads12(matchingGEMPads(clct1a->bestCLCT[bx_clct], alct->secondALCT[bx_alct], coPads_[bx_alct], ME1A, false));
785  const auto& matchingCoPads21(matchingGEMPads(clct1a->secondCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_alct], ME1A, false));
786  const auto& matchingCoPads22(matchingGEMPads(clct1a->secondCLCT[bx_clct], alct->secondALCT[bx_alct], coPads_[bx_alct], ME1A, false));
787  GEMPadsBX matchingCoPads;
788  matchingCoPads.reserve(matchingCoPads11.size() +
789  matchingCoPads12.size() +
790  matchingCoPads21.size() +
791  matchingCoPads22.size()
792  );
793  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads11), std::end(matchingCoPads11));
794  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads12), std::end(matchingCoPads12));
795  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads21), std::end(matchingCoPads21));
796  matchingCoPads.insert(std::end(matchingCoPads), std::begin(matchingCoPads22), std::end(matchingCoPads22));
797 
798  if (runME11ILT_ and dropLowQualityCLCTsNoGEMs_ME1a_ and quality < 4 and hasPads){
799  int nFound(!matchingPads.empty());
800  const bool clctInEdge(clct1a->bestCLCT[bx_clct].getKeyStrip() < 4 or clct1a->bestCLCT[bx_clct].getKeyStrip() > 93);
801  if (clctInEdge){
802  if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT in CSC chamber edge, don't care about GEM pads" << std::endl;
803  }
804  else {
805  if (nFound != 0){
806  if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT with " << nFound << " matching GEM trigger pads" << std::endl;
807  }
808  else {
809  if (debug_gem_matching) std::cout << "\tWarning: low quality CLCT without matching GEM trigger pad" << std::endl;
810  continue;
811  }
812  }
813  }
814  ++nSuccesFulMatches;
815  hasLCTs = true;
816  int mbx = bx_clct-bx_clct_start;
817  correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
818  clct1a->bestCLCT[bx_clct], clct1a->secondCLCT[bx_clct],
819  allLCTs1a[bx_alct][mbx][0], allLCTs1a[bx_alct][mbx][1], ME1A, matchingPads, matchingCoPads);
820  if (debug_gem_matching) {
821  std::cout << "Successful ALCT-CLCT match in ME1a: bx_alct = " << bx_alct
822  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
823  << "]; bx_clct = " << bx_clct << std::endl;
824  std::cout << "+++ Best CLCT Details: " << clct1a->bestCLCT[bx_clct] << std::endl;
825  if (not clct1a->secondCLCT[bx_clct].isValid())
826  std::cout << "+++ Second CLCT INVALID" << std::endl;
827  else
828  std::cout << "+++ Second CLCT Details: " << clct1a->secondCLCT[bx_clct] << std:: endl;
829  }
830  if (allLCTs1a[bx_alct][mbx][0].isValid()){
831  used_clct_mask_1a[bx_clct] += 1;
833  }
834  }
835  }
836 
837  if (nSuccesFulMatches==0)
838  if (debug_gem_matching) std::cout << "++No valid ALCT-CLCT matches in ME1a" << std::endl;
839 
840  // ALCT-to-GEM matching in ME1a
841  nSuccesFulGEMMatches = 0;
842  if (runME11ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandGEM_ME1a_){
843  for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) {
844  std::cout <<"ALCT-to-GEM matching in ME1a, bx_gem "<< bx_gem << std::endl;
845 
846  // find the best matching copad - first one
847  const auto& copads1(matchingGEMPads(alct->bestALCT[bx_alct], coPads_[bx_gem], ME1A, false));
848  const auto& copads2(matchingGEMPads(alct->secondALCT[bx_alct], coPads_[bx_gem], ME1A, false));
849  GEMPadsBX copads;
850  copads.reserve(copads1.size() +
851  copads2.size()
852  );
853  copads.insert(std::end(copads), std::begin(copads1), std::end(copads1));
854  copads.insert(std::end(copads), std::begin(copads2), std::end(copads2));
855 
856  if (debug_gem_matching) std::cout << "\t++Number of matching GEM CoPads in BX " << bx_alct << " : "<< copads.size() << std::endl;
857  if (copads.empty()) {
858  continue;
859  }
860 
861  correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
862  copads.at(0).second, allLCTs1a[bx_alct][0][0], allLCTs1a[bx_alct][0][1], ME1A);
863  if (allLCTs1a[bx_alct][0][0].isValid()) {
864  ++nSuccesFulGEMMatches;
866  }
867  if (debug_gem_matching) {
868  std::cout << "Successful ALCT-GEM CoPad match in ME1a: bx_alct = " << bx_alct << std::endl << std::endl;
869  std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
870  }
871  }
872  }
873 
874  if (debug_gem_matching) {
875  std::cout << "========================================================================" << std::endl;
876  std::cout << "Summary: " << std::endl;
877  if (nSuccesFulMatches>1)
878  std::cout << "Too many successful ALCT-CLCT matches in ME1a: " << nSuccesFulMatches
879  << ", CSCDetId " << cscChamberME1a->id()
880  << ", bx_alct = " << bx_alct
881  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
882  else if (nSuccesFulMatches==1)
883  std::cout << "1 successful ALCT-CLCT match in ME1a: "
884  << " CSCDetId " << cscChamberME1a->id()
885  << ", bx_alct = " << bx_alct
886  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
887  else if (nSuccesFulGEMMatches==1)
888  std::cout << "1 successful ALCT-GEM match in ME1a: "
889  << " CSCDetId " << cscChamberME1a->id()
890  << ", bx_alct = " << bx_alct
891  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
892  else
893  std::cout << "Unsuccessful ALCT-CLCT match in ME1a: "
894  << "CSCDetId " << cscChamberME1a->id()
895  << ", bx_alct = " << bx_alct
896  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
897  }
898 
899  } // end of ALCT valid block
900  else {
901  auto coPads(coPads_[bx_alct]);
902  if (runME11ILT_ and !coPads.empty()) {
903  // keep it simple for the time being, only consider the first copad
904  const int bx_clct_start(bx_alct - match_trig_window_size/2);
905  const int bx_clct_stop(bx_alct + match_trig_window_size/2);
906 
907  // matching in ME1b
908  if (buildLCTfromCLCTandGEM_ME1b_ and not allLCTs1b[bx_alct][0][0].isValid()) {
909  if (debug_gem_matching){
910  std::cout << "========================================================================" << std::endl;
911  std::cout <<"GEM-CLCT matching in ME1/b chamber: "<< cscChamberME1b->id()<< "in bx:"<<bx_alct<<std::endl;
912  std::cout << "------------------------------------------------------------------------" << std::endl;
913  }
914 
915  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) {
916  if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
917  if (drop_used_clcts and used_clct_mask[bx_clct]) continue;
918  if (clct->bestCLCT[bx_clct].isValid()) {
919  const int quality(clct->bestCLCT[bx_clct].getQuality());
920  // only use high-Q stubs for the time being
921  if (quality < 4) continue;
922  int mbx = bx_clct-bx_clct_start;
923  correlateLCTsGEM(clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct], coPads[0].second, GEMDetId(coPads[0].first).roll(),
924  allLCTs1b[bx_alct][mbx][0], allLCTs1b[bx_alct][mbx][1], ME1B);
925  if (debug_gem_matching) {
926  // if (infoV > 1) LogTrace("CSCMotherboard")
927  std::cout << "Successful GEM-CLCT match in ME1b: bx_alct = " << bx_alct
928  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
929  << "]; bx_clct = " << bx_clct << std::endl;
930  std::cout << "+++ Best CLCT Details: " << clct->bestCLCT[bx_clct] << std::endl;
931  if (not clct->secondCLCT[bx_clct].isValid())
932  std::cout << "+++ Second CLCT INVALID" << std::endl;
933  else
934  std::cout << "+++ Second CLCT Details: " << clct->secondCLCT[bx_clct] << std:: endl;
935  }
936  if (allLCTs1b[bx_alct][mbx][0].isValid()) {
937  used_clct_mask[bx_clct] += 1;
939  }
940  }
941  }
942  }
943 
944  // matching in ME1a
945  if (buildLCTfromCLCTandGEM_ME1a_ and not allLCTs1a[bx_alct][0][0].isValid()) {
946  if (debug_gem_matching){
947  std::cout << "========================================================================" << std::endl;
948  std::cout <<"GEM-CLCT matching in ME1/a chamber: "<< cscChamberME1a->id()<< "in bx:"<<bx_alct<<std::endl;
949  std::cout << "------------------------------------------------------------------------" << std::endl;
950  }
951  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) {
952  if (bx_clct < 0 || bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
953  if (drop_used_clcts && used_clct_mask_1a[bx_clct]) continue;
954  if (clct1a->bestCLCT[bx_clct].isValid()){
955  const int quality(clct1a->bestCLCT[bx_clct].getQuality());
956  // only use high-Q stubs for the time being
957  if (quality < 4) continue;
958  int mbx = bx_clct-bx_clct_start;
959  correlateLCTsGEM(clct1a->bestCLCT[bx_clct], clct1a->secondCLCT[bx_clct], coPads[0].second, GEMDetId(coPads[0].first).roll(),
960  allLCTs1a[bx_alct][mbx][0], allLCTs1a[bx_alct][mbx][1], ME1A);
961  if (debug_gem_matching) {
962  // if (infoV > 1) LogTrace("CSCMotherboard")
963  std::cout << "Successful GEM-CLCT match in ME1a: bx_alct = " << bx_alct
964  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
965  << "]; bx_clct = " << bx_clct << std::endl;
966  std::cout << "+++ Best CLCT Details: " << clct1a->bestCLCT[bx_clct] << std::endl;
967  if (not clct1a->secondCLCT[bx_clct].isValid())
968  std::cout << "+++ Second CLCT INVALID" << std::endl;
969  else
970  std::cout << "+++ Second CLCT Details: " << clct1a->secondCLCT[bx_clct] << std:: endl;
971  }
972  if (allLCTs1a[bx_alct][mbx][0].isValid()){
973  used_clct_mask_1a[bx_clct] += 1;
975  }
976  }
977  }
978  }
979  }
980  }
981  } // end of ALCT-centric matching
982 
983  if (hasLCTs and debug_gem_matching){
984  std::cout << "========================================================================" << std::endl;
985  std::cout << "Counting the LCTs" << std::endl;
986  std::cout << "========================================================================" << std::endl;
987  }else if (debug_gem_matching){
988  std::cout << "========================================================================" << std::endl;
989  std::cout << "Counting the LCTs: No LCT is Built" << std::endl;
990  std::cout << "========================================================================" << std::endl;
991  }
992 
993  // reduction of nLCTs per each BX
994  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
995  {
996  // counting
997  unsigned int n1a=0, n1b=0;
998  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
999  for (int i=0;i<2;i++)
1000  {
1001  int cbx = bx + mbx - match_trig_window_size/2;
1002  if (allLCTs1b[bx][mbx][i].isValid())
1003  {
1004  n1b++;
1005  if (infoV > 0) LogDebug("CSCMotherboard")
1006  << "1b LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1b[bx][mbx][i]<<std::endl;
1007  }
1008  if (allLCTs1a[bx][mbx][i].isValid())
1009  {
1010  n1a++;
1011  if (infoV > 0) LogDebug("CSCMotherboard")
1012  << "1a LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1a[bx][mbx][i]<<std::endl;
1013  }
1014  }
1015  if (infoV > 0 and n1a+n1b>0) LogDebug("CSCMotherboard")
1016  <<"bx "<<bx<<" nLCT:"<<n1a<<" "<<n1b<<" "<<n1a+n1b<<std::endl;
1017 
1018  // some simple cross-bx sorting algorithms
1019  if (tmb_cross_bx_algo == 1 and (n1a>2 or n1b>2) )
1020  {
1021  n1a=0, n1b=0;
1022  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1023  for (int i=0;i<2;i++)
1024  {
1025  if (allLCTs1b[bx][pref[mbx]][i].isValid())
1026  {
1027  n1b++;
1028  if (n1b>2) allLCTs1b[bx][pref[mbx]][i].clear();
1029  }
1030  if (allLCTs1a[bx][pref[mbx]][i].isValid())
1031  {
1032  n1a++;
1033  if (n1a>2) allLCTs1a[bx][pref[mbx]][i].clear();
1034  }
1035  }
1036 
1037  n1a=0, n1b=0;
1038  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1039  for (int i=0;i<2;i++)
1040  {
1041  int cbx = bx + mbx - match_trig_window_size/2;
1042  if (allLCTs1b[bx][mbx][i].isValid())
1043  {
1044  n1b++;
1045  if (infoV > 0) LogDebug("CSCMotherboard")
1046  << "1b LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1b[bx][mbx][i]<<std::endl;
1047  }
1048  if (allLCTs1a[bx][mbx][i].isValid())
1049  {
1050  n1a++;
1051  if (infoV > 0) LogDebug("CSCMotherboard")
1052  << "1a LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs1a[bx][mbx][i]<<std::endl;
1053  }
1054  }
1055  if (infoV > 0 and n1a+n1b>0) LogDebug("CSCMotherboard")
1056  <<"bx "<<bx<<" nnLCT:"<<n1a<<" "<<n1b<<" "<<n1a+n1b<<std::endl;
1057  } // x-bx sorting
1058 
1059  // Maximum 2 per whole ME11 per BX case:
1060  // (supposedly, now we should have max 2 per bx in each 1a and 1b)
1061  if (n1a+n1b > max_me11_lcts and tmb_cross_bx_algo == 1)
1062  {
1063  // do it simple so far: take all low eta 1/b stubs
1064  unsigned int nLCT=n1b;
1065  n1a=0;
1066  // right now nLCT<=2; cut 1a if necessary
1067  for (unsigned int mbx=0; mbx<match_trig_window_size; mbx++)
1068  for (int i=0;i<2;i++)
1069  if (allLCTs1a[bx][mbx][i].isValid()) {
1070  nLCT++;
1071  if (nLCT>max_me11_lcts) allLCTs1a[bx][mbx][i].clear();
1072  else n1a++;
1073  }
1074  // if (infoV > 0 and nLCT>0) LogDebug("CSCMotherboard")
1075 // std::cout <<"bx "<<bx<<" nnnLCT: "<<n1a<<" "<<n1b<<" "<<n1a+n1b<<std::endl;
1076  }
1077  }// reduction per bx
1078 
1079  bool first = true;
1080  unsigned int n1b=0, n1a=0;
1081  for (const auto& p : readoutLCTs1b())
1082  {
1083  if (debug_gem_matching and first){
1084  std::cout << "========================================================================" << std::endl;
1085  std::cout << "Counting the final LCTs" << std::endl;
1086  std::cout << "========================================================================" << std::endl;
1087  first = false;
1088  std::cout << "tmb_cross_bx_algo: " << tmb_cross_bx_algo << std::endl;
1089 
1090  }
1091  n1b++;
1092  if (debug_gem_matching)
1093  std::cout << "1b LCT "<<n1b<<" " << p <<std::endl;
1094  }
1095 
1096  for (const auto& p : readoutLCTs1a())
1097  {
1098  if (debug_gem_matching and first){
1099  std::cout << "========================================================================" << std::endl;
1100  std::cout << "Counting the final LCTs" << std::endl;
1101  std::cout << "========================================================================" << std::endl;
1102  first = false;
1103  std::cout << "tmb_cross_bx_algo: " << tmb_cross_bx_algo << std::endl;
1104  }
1105  n1a++;
1106  if (debug_gem_matching)
1107  std::cout << "1a LCT "<<n1a<<" " << p <<std::endl;
1108  }
1109 
1110  if (debug_gem_matching){
1111  std::cout << "Summarize LCTs, ME1b nLCT "<< n1b <<" ME1a nLCT "<< n1a << std::endl;
1112  std::cout << "========================================================================" << std::endl;
1113  }
1114 
1115  // if (infoV > 1) LogTrace("CSCMotherboardME11GEM")<<"clct_count E:"<<theEndcap<<"S:"<<theStation<<"R:"<<1<<"C:"
1116  // <<CSCTriggerNumbering::chamberFromTriggerLabels(theSector,theSubsector, theStation, theTrigChamber)
1117  // <<" a "<<n_clct_a<<" b "<<n_clct_b<<" ab "<<n_clct_a+n_clct_b;
1118 }
1119 
1120 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::readoutLCTs1a()
1121 {
1122  return readoutLCTs(ME1A);
1123 }
1124 
1125 
1126 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::readoutLCTs1b()
1127 {
1128  return readoutLCTs(ME1B);
1129 }
1130 
1131 
1132 // Returns vector of read-out correlated LCTs, if any. Starts with
1133 // the vector of all found LCTs and selects the ones in the read-out
1134 // time window.
1135 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::readoutLCTs(enum ME11Part me1ab)
1136 {
1137  std::vector<CSCCorrelatedLCTDigi> tmpV;
1138 
1139  // The start time of the L1A*LCT coincidence window should be related
1140  // to the fifo_pretrig parameter, but I am not completely sure how.
1141  // Just choose it such that the window is centered at bx=7. This may
1142  // need further tweaking if the value of tmb_l1a_window_size changes.
1143  //static int early_tbins = 4;
1144  // The number of LCT bins in the read-out is given by the
1145  // tmb_l1a_window_size parameter, forced to be odd
1146  static int lct_bins =
1148  static int late_tbins = early_tbins + lct_bins;
1149 
1150 
1151  // Start from the vector of all found correlated LCTs and select
1152  // those within the LCT*L1A coincidence window.
1153  int bx_readout = -1;
1154  std::vector<CSCCorrelatedLCTDigi> tmp_lcts;
1155  std::vector<CSCCorrelatedLCTDigi> all_lcts;
1156  if (me1ab == ME1A) tmp_lcts = getLCTs1a();
1157  if (me1ab == ME1B) tmp_lcts = getLCTs1b();
1158  switch(tmb_cross_bx_algo){
1159  case 0: all_lcts = tmp_lcts;
1160  break;
1161  case 1: all_lcts = tmp_lcts;
1162  break;
1163  case 2: all_lcts = sortLCTsByQuality(me1ab);
1164  break;
1165  case 3: all_lcts = sortLCTsByGEMDPhi(me1ab);
1166  break;
1167  default: std::cout<<"tmb_cross_bx_algo error" <<std::endl;
1168  break;
1169  }
1170  std::vector <CSCCorrelatedLCTDigi>::const_iterator plct = all_lcts.begin();
1171  for (; plct != all_lcts.end(); plct++)
1172  {
1173  if (!plct->isValid()) continue;
1174 
1175  int bx = (*plct).getBX();
1176  // Skip LCTs found too early relative to L1Accept.
1177  if (bx <= early_tbins) continue;
1178 
1179  // Skip LCTs found too late relative to L1Accept.
1180  if (bx > late_tbins) continue;
1181 
1182  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
1183  // in digi->raw step, LCTs have to be packed into the TMB header, and
1184  // currently there is room just for two.
1185  if (readout_earliest_2 and (bx_readout == -1 or bx == bx_readout) )
1186  {
1187  tmpV.push_back(*plct);
1188  if (bx_readout == -1) bx_readout = bx;
1189  }
1190  else tmpV.push_back(*plct);
1191  }
1192  return tmpV;
1193 }
1194 
1195 
1196 // Returns vector of found correlated LCTs, if any.
1197 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::getLCTs1b()
1198 {
1199  std::vector<CSCCorrelatedLCTDigi> tmpV;
1200 
1201  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
1202  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1203  for (int i=0;i<2;i++)
1204  if (allLCTs1b[bx][mbx][i].isValid()) tmpV.push_back(allLCTs1b[bx][mbx][i]);
1205  return tmpV;
1206 }
1207 
1208 
1209 // Returns vector of found correlated LCTs, if any.
1210 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::getLCTs1a()
1211 {
1212  std::vector<CSCCorrelatedLCTDigi> tmpV;
1213 
1214  // disabled ME1a
1215  if (mpc_block_me1a or disableME1a) return tmpV;
1216 
1217  // Report all LCTs found.
1218  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
1219  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1220  for (int i=0;i<2;i++)
1221  if (allLCTs1a[bx][mbx][i].isValid()) tmpV.push_back(allLCTs1a[bx][mbx][i]);
1222  return tmpV;
1223 }
1224 
1225 
1226 //sort LCTs by Quality in each BX
1227 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::sortLCTsByQuality(int bx, enum ME11Part me)
1228 {
1229  auto allLCTs(me==ME1A ? allLCTs1a : allLCTs1b);
1230  std::vector<CSCCorrelatedLCTDigi> LCTs;
1231  std::vector<CSCCorrelatedLCTDigi> tmpV;
1232  tmpV.clear();
1233  LCTs.clear();
1234  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1235  for (int i=0;i<2;i++)
1236  if (allLCTs[bx][mbx][i].isValid())
1237  LCTs.push_back(allLCTs[bx][mbx][i]);
1238 
1239  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByQuality);
1240  tmpV = LCTs;
1241  if (tmpV.size()> max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end());
1242  return tmpV;
1243 }
1244 
1245 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::sortLCTsByQuality(std::vector<CSCCorrelatedLCTDigi> LCTs)
1246 {
1247  std::vector<CSCCorrelatedLCTDigi> tmpV;
1248  tmpV.clear();
1249  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByQuality);
1250  tmpV = LCTs;
1251  if (tmpV.size()> max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end());
1252  return tmpV;
1253 }
1254 
1255 
1256 //sort LCTs in whole LCTs BX window
1257 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::sortLCTsByQuality(enum ME11Part me)
1258 {
1259  std::vector<CSCCorrelatedLCTDigi> LCTs_final;
1260  LCTs_final.clear();
1261  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
1262  {
1263  // get sorted LCTs per subchamber
1264  const auto& LCTs1a = sortLCTsByQuality(bx, ME1A);
1265  const auto& LCTs1b = sortLCTsByQuality(bx, ME1B);
1266 
1267  // temporary collection with all LCTs in the whole chamber
1268  std::vector<CSCCorrelatedLCTDigi> LCTs_tmp;
1269  LCTs_tmp.insert(LCTs_tmp.begin(), LCTs1b.begin(), LCTs1b.end());
1270  LCTs_tmp.insert(LCTs_tmp.end(), LCTs1a.begin(), LCTs1a.end());
1271 
1272  // sort the selected LCTs
1273  LCTs_tmp = sortLCTsByQuality(LCTs_tmp);
1274 
1275  //LCTs reduction per BX
1276  if (max_me11_lcts==2)
1277  {
1278  // loop on all the selected LCTs
1279  for (const auto& p: LCTs_tmp){
1280  // case when you only want to readout ME1A
1281  if (me==ME1A and std::find(LCTs1a.begin(), LCTs1a.end(), p) != LCTs1a.end()){
1282  LCTs_final.push_back(p);
1283  }
1284  // case when you only want to readout ME1B
1285  else if(me==ME1B and std::find(LCTs1b.begin(), LCTs1b.end(), p) != LCTs1b.end()){
1286  LCTs_final.push_back(p);
1287  }
1288  }
1289  }
1290  else {
1291  if (!LCTs1a.empty() and !LCTs1b.empty() and me==ME1A)
1292  LCTs_final.push_back(*LCTs1a.begin());
1293  else if (!LCTs1a.empty() and !LCTs1b.empty() and me==ME1B)
1294  LCTs_final.push_back(*LCTs1b.begin());
1295  else if (!LCTs1a.empty() and LCTs1b.empty() and me==ME1A)
1296  LCTs_final.insert(LCTs_final.end(), LCTs1a.begin(), LCTs1a.end());
1297  else if (!LCTs1b.empty() and LCTs1a.empty() and me==ME1B)
1298  LCTs_final.insert(LCTs_final.end(), LCTs1b.begin(), LCTs1b.end());
1299  }
1300  }
1301  return LCTs_final;
1302 }
1303 
1304 
1305 //sort LCTs by GEMDPhi in each BX
1306 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::sortLCTsByGEMDPhi(int bx, enum ME11Part me)
1307 {
1308 
1309  auto allLCTs(me==ME1A ? allLCTs1a : allLCTs1b);
1310  std::vector<CSCCorrelatedLCTDigi> LCTs;
1311  std::vector<CSCCorrelatedLCTDigi> tmpV;
1312  tmpV.clear();
1313  LCTs.clear();
1314  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
1315  for (int i=0;i<2;i++)
1316  if (allLCTs[bx][mbx][i].isValid())
1317  LCTs.push_back(allLCTs[bx][mbx][i]);
1318 
1319  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByGEMDphi);
1320  tmpV = LCTs;
1321  if (tmpV.size() > max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end());
1322  return tmpV;
1323 }
1324 
1325 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::sortLCTsByGEMDPhi(std::vector<CSCCorrelatedLCTDigi> LCTs)
1326 {
1327  std::vector<CSCCorrelatedLCTDigi> tmpV;
1328  tmpV.clear();
1329  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByGEMDphi);
1330  tmpV = LCTs;
1331  if (tmpV.size() > max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end());
1332  return tmpV;
1333 }
1334 
1335 
1336 //sort LCTs in whole LCTs BX window
1337 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11GEM::sortLCTsByGEMDPhi(enum ME11Part me)
1338 {
1339  std::vector<CSCCorrelatedLCTDigi> LCTs_final;
1340  LCTs_final.clear();
1341  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
1342  {
1343  // get sorted LCTs per subchamber
1344  const auto& LCTs1a = sortLCTsByGEMDPhi(bx, ME1A);
1345  const auto& LCTs1b = sortLCTsByGEMDPhi(bx, ME1B);
1346 
1347  // temporary collection with all LCTs in the whole chamber
1348  std::vector<CSCCorrelatedLCTDigi> LCTs_tmp;
1349  LCTs_tmp.insert(LCTs_tmp.begin(), LCTs1b.begin(), LCTs1b.end());
1350  LCTs_tmp.insert(LCTs_tmp.end(), LCTs1a.begin(), LCTs1a.end());
1351 
1352  // sort the selected LCTs
1353  LCTs_tmp = sortLCTsByGEMDPhi(LCTs_tmp);
1354 
1355  //LCTs reduction per BX
1356  if (max_me11_lcts==2)
1357  {
1358  // loop on all the selected LCTs
1359  for (const auto& p: LCTs_tmp){
1360  // case when you only want to readout ME1A
1361  if (me==ME1A and std::find(LCTs1a.begin(), LCTs1a.end(), p) != LCTs1a.end()){
1362  LCTs_final.push_back(p);
1363  }
1364  // case when you only want to readout ME1B
1365  else if(me==ME1B and std::find(LCTs1b.begin(), LCTs1b.end(), p) != LCTs1b.end()){
1366  LCTs_final.push_back(p);
1367  }
1368  }
1369  }
1370  else {
1371  if (!LCTs1a.empty() and !LCTs1b.empty() and me==ME1A)
1372  LCTs_final.push_back(*LCTs1a.begin());
1373  else if (!LCTs1a.empty() and !LCTs1b.empty() and me==ME1B)
1374  LCTs_final.push_back(*LCTs1b.begin());
1375  else if (!LCTs1a.empty() and LCTs1b.empty() and me==ME1A)
1376  LCTs_final.insert(LCTs_final.end(), LCTs1a.begin(), LCTs1a.end());
1377  else if (!LCTs1b.empty() and LCTs1a.empty() and me==ME1B)
1378  LCTs_final.insert(LCTs_final.end(), LCTs1b.begin(), LCTs1b.end());
1379  }
1380  }
1381  return LCTs_final;
1382 }
1383 
1384 
1386 {
1387  if ( !c.isValid() or !a.isValid() ) return false;
1388  int key_hs = c.getKeyStrip();
1389  int key_wg = a.getKeyWG();
1390  if ( me == ME1A )
1391  {
1392  if ( !gangedME1a )
1393  {
1394  // wrap around ME11 HS number for -z endcap
1395  if (theEndcap==2) key_hs = 95 - key_hs;
1396  if ( key_hs >= lut_wg_vs_hs_me1a[key_wg][0] and
1397  key_hs <= lut_wg_vs_hs_me1a[key_wg][1] ) return true;
1398  return false;
1399  }
1400  else
1401  {
1402  if (theEndcap==2) key_hs = 31 - key_hs;
1403  if ( key_hs >= lut_wg_vs_hs_me1ag[key_wg][0] and
1404  key_hs <= lut_wg_vs_hs_me1ag[key_wg][1] ) return true;
1405  return false;
1406  }
1407  }
1408  if ( me == ME1B)
1409  {
1410  if (theEndcap==2) key_hs = 127 - key_hs;
1411  if ( key_hs >= lut_wg_vs_hs_me1b[key_wg][0] and
1412  key_hs <= lut_wg_vs_hs_me1b[key_wg][1] ) return true;
1413  }
1414  return false;
1415 }
1416 
1418  CSCALCTDigi secondALCT,
1419  GEMPadDigi gemPad,
1420  CSCCorrelatedLCTDigi& lct1,
1421  CSCCorrelatedLCTDigi& lct2, int ME)
1422 {
1423  bool anodeBestValid = bestALCT.isValid();
1424  bool anodeSecondValid = secondALCT.isValid();
1425 
1426  if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT;
1427  if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT;
1428 
1429  if ((alct_trig_enable and bestALCT.isValid()) or
1430  (match_trig_enable and bestALCT.isValid()))
1431  {
1432  lct1 = constructLCTsGEM(bestALCT, gemPad, ME, useOldLCTDataFormat_);
1433  lct1.setTrknmb(1);
1434  lct1.setALCT(bestALCT);
1435  lct1.setGEM1(gemPad);
1437  }
1438 
1439  if ((alct_trig_enable and secondALCT.isValid()) or
1440  (match_trig_enable and secondALCT.isValid() and secondALCT != bestALCT))
1441  {
1442  lct2 = constructLCTsGEM(secondALCT, gemPad, ME, useOldLCTDataFormat_);
1443  lct2.setTrknmb(2);
1444  lct2.setALCT(secondALCT);
1445  lct2.setGEM1(gemPad);
1447  }
1448 }
1449 
1450 
1452  CSCCLCTDigi secondCLCT,
1453  GEMPadDigi gemPad, int roll,
1454  CSCCorrelatedLCTDigi& lct1,
1455  CSCCorrelatedLCTDigi& lct2, int ME)
1456 {
1457  bool cathodeBestValid = bestCLCT.isValid();
1458  bool cathodeSecondValid = secondCLCT.isValid();
1459 
1460  if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT;
1461  if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT;
1462 
1463  if ((clct_trig_enable and bestCLCT.isValid()) or
1464  (match_trig_enable and bestCLCT.isValid()))
1465  {
1466  lct1 = constructLCTsGEM(bestCLCT, gemPad, roll, ME, useOldLCTDataFormat_);
1467  lct1.setTrknmb(1);
1468  lct1.setCLCT(bestCLCT);
1469  lct1.setGEM1(gemPad);
1471  }
1472 
1473  if ((clct_trig_enable and secondCLCT.isValid()) or
1474  (match_trig_enable and secondCLCT.isValid() and secondCLCT != bestCLCT))
1475  {
1476  lct2 = constructLCTsGEM(secondCLCT, gemPad, roll, ME, useOldLCTDataFormat_);
1477  lct2.setTrknmb(2);
1478  lct2.setCLCT(secondCLCT);
1479  lct2.setGEM1(gemPad);
1481  }
1482 }
1483 
1485  CSCALCTDigi secondALCT,
1486  CSCCLCTDigi bestCLCT,
1487  CSCCLCTDigi secondCLCT,
1488  CSCCorrelatedLCTDigi& lct1,
1489  CSCCorrelatedLCTDigi& lct2,
1490  int me,
1491  const GEMPadsBX& pads,
1492  const GEMPadsBX& copads)
1493 {
1494  // assume that always anodeBestValid and cathodeBestValid
1495 
1496  if (secondALCT == bestALCT) secondALCT.clear();
1497  if (secondCLCT == bestCLCT) secondCLCT.clear();
1498 
1499  int ok11 = doesALCTCrossCLCT( bestALCT, bestCLCT, me);
1500  int ok12 = doesALCTCrossCLCT( bestALCT, secondCLCT, me);
1501  int ok21 = doesALCTCrossCLCT( secondALCT, bestCLCT, me);
1502  int ok22 = doesALCTCrossCLCT( secondALCT, secondCLCT, me);
1503  int code = (ok11<<3) | (ok12<<2) | (ok21<<1) | (ok22);
1504 
1505  int dbg=0;
1506  int ring = me;
1508  CSCDetId did(theEndcap, theStation, ring, chamb, 0);
1509  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"debug correlateLCTs in "<<did<<std::endl
1510  <<"ALCT1: "<<bestALCT<<std::endl
1511  <<"ALCT2: "<<secondALCT<<std::endl
1512  <<"CLCT1: "<<bestCLCT<<std::endl
1513  <<"CLCT2: "<<secondCLCT<<std::endl
1514  <<"ok 11 12 21 22 code = "<<ok11<<" "<<ok12<<" "<<ok21<<" "<<ok22<<" "<<code<<std::endl;
1515 
1516  if ( code==0 ) return;
1517 
1518  // LUT defines correspondence between possible ok## combinations
1519  // and resulting lct1 and lct2
1520  int lut[16][2] = {
1521  //ok: 11 12 21 22
1522  {0 ,0 }, // 0 0 0 0
1523  {22,0 }, // 0 0 0 1
1524  {21,0 }, // 0 0 1 0
1525  {21,22}, // 0 0 1 1
1526  {12,0 }, // 0 1 0 0
1527  {12,22}, // 0 1 0 1
1528  {12,21}, // 0 1 1 0
1529  {12,21}, // 0 1 1 1
1530  {11,0 }, // 1 0 0 0
1531  {11,22}, // 1 0 0 1
1532  {11,21}, // 1 0 1 0
1533  {11,22}, // 1 0 1 1
1534  {11,12}, // 1 1 0 0
1535  {11,22}, // 1 1 0 1
1536  {11,12}, // 1 1 1 0
1537  {11,22}, // 1 1 1 1
1538  };
1539 
1540  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"lut 0 1 = "<<lut[code][0]<<" "<<lut[code][1]<<std::endl;
1541 
1542  // first check the special case (11,22) where we have an ambiguity
1543  const int nPads(!pads.empty());
1544  const int nCoPads(!copads.empty());
1545  const bool hasPads(nPads!=0);
1546  const bool hasCoPads(nCoPads!=0);
1547 
1548  if (doLCTGhostBustingWithGEMs_ and (lut[code][0] == 11) and (lut[code][0] == 22) and hasPads and (me==ME1B)){
1549 
1550  if (debug_gem_matching) std::cout << "++Info: 2 valid ALCTs-CLCTs pairs with trigger pads." << std::endl;
1551  // first check if there are any copads
1552  typedef std::pair<int,int> mypair;
1553  // for each trigger pad, store (deltaRoll,deltaHS) for 11,22,12 and 21.
1554  std::vector<std::tuple<mypair,mypair,mypair,mypair>> deltas;
1555  deltas.clear();
1556 
1557  if (hasCoPads){
1558  for (const auto& p : copads) {
1559  const GEMDetId detId(p.first);
1560  const int rollN(detId.roll());
1561  const int padN((p.second).pad());
1562 
1563  auto t11(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN)));
1564  auto t22(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN)));
1565  auto t12(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN)));
1566  auto t21(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN)));
1567 
1568  deltas.push_back(std::make_tuple(t11,t22,t12,t21));
1569  }
1570  if (debug_gem_matching){
1571  std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl;
1572  std::cout << "Printing (deltaRoll, deltaPad) for each (ALCT,CLCT) pair and for each trigger copad" << std::endl;
1573  for (unsigned i =0; i < deltas.size(); ++i){
1574  auto c(deltas.at(i));
1575  std::cout << "\tCoPad " << i << std::endl;
1576  std::cout << "\t11: " << "(" << std::get<0>(c).first << "," << std::get<0>(c).second << "); "
1577  << "22: " << "(" << std::get<1>(c).first << "," << std::get<1>(c).second << "); "
1578  << "12: " << "(" << std::get<2>(c).first << "," << std::get<2>(c).second << "); "
1579  << "21: " << "(" << std::get<3>(c).first << "," << std::get<3>(c).second << ")" << std::endl << std::endl;
1580  }
1581  std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl;
1582  }
1583 
1584 
1585 // lct1 = constructLCTs(bestALCT, bestCLCT);
1586 // lct1.setTrknmb(1);
1587 // lct2 = constructLCTs(secondALCT, secondCLCT);
1588 // lct2.setTrknmb(2);
1589 
1590 // lct1 = constructLCTs(bestALCT, secondCLCT);
1591 // lct1.setTrknmb(1);
1592 // lct2 = constructLCTs(secondLCT, bestCLCT);
1593 // lct2.setTrknmb(2);
1594  return;
1595  }
1596 
1597  // if no copads were found, do the same with pads...
1598  if (hasPads){
1599  for (const auto& p : pads) {
1600  const GEMDetId detId(p.first);
1601  const int rollN(detId.roll());
1602  const int padN((p.second).pad());
1603 
1604  auto t11(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN)));
1605  auto t22(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN)));
1606  auto t12(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN)));
1607  auto t21(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN)));
1608 
1609  deltas.push_back(std::make_tuple(t11,t22,t12,t21));
1610  }
1611  if (debug_gem_matching){
1612  std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl;
1613  std::cout << "Printing (deltaRoll, deltaPad) for each (ALCT,CLCT) pair and for each trigger pad" << std::endl;
1614  for (unsigned i =0; i < deltas.size(); ++i){
1615  auto c(deltas.at(i));
1616  std::cout << "\tPad " << i << std::endl;
1617  std::cout << "\t11: " << "(" << std::get<0>(c).first << "," << std::get<0>(c).second << "); "
1618  << "22: " << "(" << std::get<1>(c).first << "," << std::get<1>(c).second << "); "
1619  << "12: " << "(" << std::get<2>(c).first << "," << std::get<2>(c).second << "); "
1620  << "21: " << "(" << std::get<3>(c).first << "," << std::get<3>(c).second << ")" << std::endl << std::endl;
1621  }
1622  std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl;
1623  }
1624 
1625  return;
1626  }
1627  }
1628 
1629  switch (lut[code][0]) {
1630  case 11:
1631  lct1 = constructLCTsGEM(bestALCT, bestCLCT, hasPads, hasCoPads);
1632  break;
1633  case 12:
1634  lct1 = constructLCTsGEM(bestALCT, secondCLCT, hasPads, hasCoPads);
1635  break;
1636  case 21:
1637  lct1 = constructLCTsGEM(secondALCT, bestCLCT, hasPads, hasCoPads);
1638  break;
1639  case 22:
1640  lct1 = constructLCTsGEM(secondALCT, secondCLCT, hasPads, hasCoPads);
1641  break;
1642  default:
1643  return;
1644  }
1645  lct1.setTrknmb(1);
1646 
1647  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"lct1: "<<lct1<<std::endl;
1648 
1649  switch (lut[code][1])
1650  {
1651  case 12:
1652  lct2 = constructLCTsGEM(bestALCT, secondCLCT, hasPads, hasCoPads);
1653  lct2.setTrknmb(2);
1654  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"lct2: "<<lct2<<std::endl;
1655  return;
1656  case 21:
1657  lct2 = constructLCTsGEM(secondALCT, bestCLCT, hasPads, hasCoPads);
1658  lct2.setTrknmb(2);
1659  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"lct2: "<<lct2<<std::endl;
1660  return;
1661  case 22:
1662  lct2 = constructLCTsGEM(secondALCT, secondCLCT, hasPads, hasCoPads);
1663  lct2.setTrknmb(2);
1664  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"lct2: "<<lct2<<std::endl;
1665  return;
1666  default:
1667  return;
1668  }
1669  if (dbg) LogTrace("CSCMotherboardME11GEM")<<"out of correlateLCTs"<<std::endl;
1670 
1671  return;
1672 }
1673 
1674 
1676 {
1677  int ch(isEven ? 2 : 1);
1678  auto chamber(gem_g->chamber(GEMDetId(1,1,1,1,ch,0)));
1679  if (chamber==nullptr) return;
1680 
1681  int n = 1;
1682  for(auto roll : chamber->etaPartitions()) {
1683  const float half_striplength(roll->specs()->specificTopology().stripLength()/2.);
1684  const LocalPoint lp_top(0., half_striplength, 0.);
1685  const LocalPoint lp_bottom(0., -half_striplength, 0.);
1686  const GlobalPoint gp_top(roll->toGlobal(lp_top));
1687  const GlobalPoint gp_bottom(roll->toGlobal(lp_bottom));
1688  gemRollToEtaLimits_[n] = std::make_pair(gp_top.eta(), gp_bottom.eta());
1689  ++n;
1690  }
1691 }
1692 
1693 
1695 {
1696  int result = -99;
1697  for (const auto& p : gemRollToEtaLimits_) {
1698  const float minEta((p.second).first);
1699  const float maxEta((p.second).second);
1700  if (minEta <= eta and eta <= maxEta) {
1701  result = p.first;
1702  break;
1703  }
1704  }
1705  return result;
1706 }
1707 
1708 
1710  const GEMPadDigi& gem,
1711  int ME, bool oldDataFormat)
1712 {
1713  std::cout << "Constructing ALCT-GEM LCT in "<<(ME==ME1A ? "ME1a":"ME1b") << std::endl;
1714  auto mymap(ME==ME1A ? gemPadToCscHsME1a_ : gemPadToCscHsME1b_);
1715  auto wgvshs(ME==ME1A ? lut_wg_vs_hs_me1a : lut_wg_vs_hs_me1b);
1716  if (oldDataFormat){
1717  // CLCT pattern number - set it to a highest value
1718  // hack to get LCTs in the CSCTF
1719  unsigned int pattern = promoteALCTGEMpattern_ ? 10 : 0;
1720 
1721  // LCT quality number - set it to a very high value
1722  // hack to get LCTs in the CSCTF
1723  unsigned int quality = promoteALCTGEMquality_ ? 15 : 11;
1724 
1725  // Bunch crossing
1726  int bx = alct.getBX();
1727 
1728  // get keyStrip from LUT
1729  int keyStrip = mymap[gem.pad()];
1730 
1731  // get wiregroup from ALCT
1732  int wg = alct.getKeyWG();
1733 
1734  if (keyStrip>wgvshs[wg][0] && keyStrip<wgvshs[wg][1])
1735  { // construct correlated LCT; temporarily assign track number of 0.
1736  return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber);
1737  }
1738  else return CSCCorrelatedLCTDigi(0,0,0,0,0,0,0,0,0,0,0,0);
1739  }
1740  else {
1741 
1742  // CLCT pattern number - no pattern
1743  unsigned int pattern = 0;
1744 
1745  // LCT quality number
1746  unsigned int quality = 1;
1747 
1748  // Bunch crossing
1749  int bx = gem.bx() + lct_central_bx;
1750 
1751  // get keyStrip from LUT
1752  int keyStrip = mymap[gem.pad()];
1753 
1754  // get wiregroup from ALCT
1755  int wg = alct.getKeyWG();
1756 
1757  if (keyStrip>wgvshs[wg][0] && keyStrip<wgvshs[wg][1])
1758  { // construct correlated LCT; temporarily assign track number of 0.
1759  return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber);
1760  }
1761  else return CSCCorrelatedLCTDigi(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1762  }
1763 }
1764 
1766  const GEMPadDigi& gem, int roll,
1767  int ME, bool oldDataFormat)
1768 {
1769  // auto mymap(ME==ME1A ? gemPadToCscHsME1a_ : gemPadToCscHsME1b_);
1770  if (oldDataFormat){
1771  // CLCT pattern number - no pattern
1772  unsigned int pattern = encodePatternGEM(clct.getPattern(), clct.getStripType());
1773 
1774  // LCT quality number - dummy quality
1775  const bool promoteCLCTGEMquality(ME == ME1A ? promoteCLCTGEMquality_ME1a_:promoteCLCTGEMquality_ME1b_);
1776  unsigned int quality = promoteCLCTGEMquality ? 15 : 11;
1777 
1778  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
1779  int bx = gem.bx() + lct_central_bx;;
1780 
1781  // pick a random WG in the roll range
1782  int wg(5);
1783 
1784  // construct correlated LCT; temporarily assign track number of 0.
1785  return CSCCorrelatedLCTDigi(0, 1, quality, wg, clct.getKeyStrip(), pattern, clct.getBend(), bx, 0, 0, 0, theTrigChamber);
1786  }
1787  else {
1788  // CLCT pattern number - no pattern
1789  unsigned int pattern = encodePatternGEM(clct.getPattern(), clct.getStripType());
1790 
1791  // LCT quality number - dummy quality
1792  unsigned int quality = 5;//findQualityGEM(alct, gem);
1793 
1794  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
1795  int bx = gem.bx() + lct_central_bx;;
1796 
1797  // ALCT WG
1798  int wg(5);
1799 
1800  // construct correlated LCT; temporarily assign track number of 0.
1801  return CSCCorrelatedLCTDigi(0, 1, quality, wg, 0, pattern, 0, bx, 0, 0, 0, theTrigChamber);
1802  }
1803 }
1804 
1805 
1807  bool hasPad, bool hasCoPad)
1808 {
1809  // CLCT pattern number
1810  unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType());
1811 
1812  // LCT quality number
1813  unsigned int quality = findQualityGEM(aLCT, cLCT, hasPad, hasCoPad);
1814 
1815  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
1816  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
1817 
1818  // construct correlated LCT; temporarily assign track number of 0.
1819  int trknmb = 0;
1820  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
1821  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
1822  bx, 0, 0, 0, theTrigChamber);
1823  thisLCT.setALCT(aLCT);
1824  thisLCT.setCLCT(cLCT);
1825  if (hasPad) thisLCT.setType(CSCCorrelatedLCTDigi::ALCTCLCTGEM);
1826  if (hasCoPad) thisLCT.setType(CSCCorrelatedLCTDigi::ALCTCLCT2GEM);
1827  return thisLCT;
1828 }
1829 
1830 
1831 unsigned int CSCMotherboardME11GEM::encodePatternGEM(const int ptn, const int highPt)
1832 {
1833  return 0;
1834 }
1835 
1836 
1837 unsigned int CSCMotherboardME11GEM::findQualityGEM(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT,
1838  bool hasPad, bool hasCoPad)
1839 {
1840 
1841  /*
1842  Same LCT quality definition as standard LCTs
1843  c4 takes GEMs into account!!!
1844  */
1845 
1846  unsigned int quality = 0;
1847 
1848  // 2008 definition.
1849  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
1850  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
1851  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
1852  else quality = 0; // both absent; should never happen.
1853  }
1854  else {
1855  int pattern = cLCT.getPattern();
1856  if (pattern == 1) quality = 3; // layer-trigger in CLCT
1857  else {
1858  // CLCT quality is the number of layers hit minus 3.
1859  // CLCT quality is the number of layers hit.
1860  // const int n_gem((pad!=NULL and 1) or (copad!=NULL and 2));
1861  int n_gem = 0;
1862  if (hasPad) n_gem = 1;
1863  if (hasCoPad) n_gem = 2;
1864  const bool a4(aLCT.getQuality() >= 1);
1865  const bool c4((cLCT.getQuality() >= 4) or (cLCT.getQuality() >= 3 and n_gem>=1));
1866  // quality = 4; "reserved for low-quality muons in future"
1867  if (!a4 && !c4) quality = 5; // marginal anode and cathode
1868  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
1869  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
1870  else if ( a4 && c4) {
1871  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
1872  else {
1873  // quality = 9; "reserved for HQ muons with future patterns
1874  // quality = 10; "reserved for HQ muons with future patterns
1875  if (pattern == 2 || pattern == 3) quality = 11;
1876  else if (pattern == 4 || pattern == 5) quality = 12;
1877  else if (pattern == 6 || pattern == 7) quality = 13;
1878  else if (pattern == 8 || pattern == 9) quality = 14;
1879  else if (pattern == 10) quality = 15;
1880  else {
1881  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
1882  << "+++ findQuality: Unexpected CLCT pattern id = "
1883  << pattern << "+++\n";
1884  }
1885  }
1886  }
1887  }
1888  }
1889  return quality;
1890 }
1891 
1892 
1893 unsigned int CSCMotherboardME11GEM::findQualityGEM(const CSCCLCTDigi& cLCT, const GEMPadDigi& gem)
1894 {
1895  return 0;
1896 }
1897 
1898 
1899 void CSCMotherboardME11GEM::printGEMTriggerPads(int bx_start, int bx_stop, bool iscopad)
1900 {
1901  // pads or copads?
1902  auto thePads(!iscopad ? pads_ : coPads_);
1903  const bool hasPads(!thePads.empty());
1904 
1905  std::cout << "------------------------------------------------------------------------" << std::endl;
1906  if (!iscopad) std::cout << "* GEM trigger pads ["<< bx_start <<","<< bx_stop <<"]: " << std::endl;
1907  else std::cout << "* GEM trigger coincidence pads ["<< bx_start <<","<< bx_stop <<"]: " << std::endl;
1908 
1909  for (int bx = bx_start; bx <= bx_stop; bx++) {
1910  // print only the pads for the central BX
1911  if (bx!=lct_central_bx and iscopad) continue;
1912  std::vector<std::pair<unsigned int, GEMPadDigi> > in_pads = thePads[bx];
1913  if (!iscopad) std::cout << "N(pads) BX " << bx << " : " << in_pads.size() << std::endl;
1914  else std::cout << "N(copads) BX " << bx << " : " << in_pads.size() << std::endl;
1915  if (hasPads){
1916  for (const auto& pad : in_pads){
1917  auto roll_id(GEMDetId(pad.first));
1918  std::cout << "\t" << roll_id << ", pad = " << pad.second.pad() << ", BX = " << pad.second.bx() + 6;
1919  if (isPadInOverlap(roll_id.roll())) std::cout << " (in overlap)" << std::endl;
1920  else std::cout << std::endl;
1921  }
1922  }
1923  else
1924  break;
1925  }
1926 }
1927 
1929 {
1930  auto superChamber(gem_g->superChamber(id));
1931  for (const auto& ch : superChamber->chambers()) {
1932  for (const auto& roll : ch->etaPartitions()) {
1933  GEMDetId roll_id(roll->id());
1934  auto pads_in_det = gemPads->get(roll_id);
1935  for (auto pad = pads_in_det.first; pad != pads_in_det.second; ++pad) {
1936  const int bx_shifted(lct_central_bx + pad->bx());
1937  for (int bx = bx_shifted - maxDeltaBXPad_;bx <= bx_shifted + maxDeltaBXPad_; ++bx) {
1938  pads_[bx].push_back(std::make_pair(roll_id, *pad));
1939  }
1940  }
1941  }
1942  }
1943 }
1944 
1946 {
1948  int region((theEndcap == 1) ? 1: -1);
1949  for (const auto& copad: gemCoPadV){
1950  auto detId1(GEMDetId(region, 1, 1, 1, gemChamber, copad.roll()));
1951  auto detId2(GEMDetId(region, 1, 1, 2, gemChamber, copad.roll()));
1952 
1953  coPads_[lct_central_bx + copad.bx(1)].push_back(std::make_pair(detId1, copad.first()));
1954  coPads_[lct_central_bx + copad.bx(1)].push_back(std::make_pair(detId2, copad.second()));
1955  }
1956 }
1957 
1959 {
1960  for (const auto& p : cscWgToGemRoll_) {
1961  // overlap region are WGs 10-15
1962  if ((p.first < 10) or (p.first > 15)) continue;
1963  if (((p.second).first <= roll) and (roll <= (p.second).second)) return true;
1964  }
1965  return false;
1966 }
1967 
1968 
1970 {
1971  const auto p(cscWgToGemRoll_[wg]);
1972  return std::min(std::abs(p.first - pad), std::abs(p.second - pad));
1973 }
1974 
1975 
1977 {
1978  const auto p(cscHsToGemPadME1b_[hs]);
1979  return std::min(std::abs(p.first - pad), std::abs(p.second - pad));
1980 }
1981 
1982 
1985 {
1987  if (not clct.isValid()) return result;
1988 
1989  // fetch the low and high pad edges
1990  auto mymap(part==ME1A ? cscHsToGemPadME1a_ : cscHsToGemPadME1b_);
1991  int deltaPad(isCoPad ? maxDeltaPadCoPad_ : maxDeltaPadPad_);
1992  int deltaBX(isCoPad ? maxDeltaBXCoPad_ : maxDeltaBXPad_);
1993  int clct_bx = clct.getBX();
1994  const int lowPad(mymap[clct.getKeyStrip()].first);
1995  const int highPad(mymap[clct.getKeyStrip()].second);
1996  const bool debug(false);
1997  if (debug) std::cout << "CLCT lowpad " << lowPad << " highpad " << highPad << " delta pad " << deltaPad <<std::endl;
1998  for (const auto& p: pads){
1999  if (DetId(p.first).subdetId() != MuonSubdetId::GEM or DetId(p.first).det() != DetId::Muon) {
2000  continue;
2001  }
2002  auto padRoll((p.second).pad());
2003  int pad_bx = (p.second).bx()+lct_central_bx;
2004  if (debug) std::cout << "Candidate GEMPad: " << p.second << std::endl;
2005  if (std::abs(clct_bx-pad_bx)>deltaBX) continue;
2006  if (std::abs(lowPad - padRoll) <= deltaPad or std::abs(padRoll - highPad) <= deltaPad){
2007  if (debug) std::cout << "++Matches! " << std::endl;
2008  result.push_back(p);
2009  if (first) return result;
2010  }
2011  }
2012  return result;
2013 }
2014 
2015 
2018 {
2020  if (not alct.isValid()) return result;
2021 
2022  auto alctRoll(cscWgToGemRoll_[alct.getKeyWG()]);
2023  int deltaBX(isCoPad ? maxDeltaBXCoPad_ : maxDeltaBXPad_);
2024  int alct_bx = alct.getBX();
2025  const bool debug(false);
2026  if (debug) std::cout << "ALCT keyWG " << alct.getKeyWG() << ", rolls " << alctRoll.first << " " << alctRoll.second <<" bx "<< alct_bx << std::endl;
2027  for (const auto& p: pads){
2028  if (DetId(p.first).subdetId() != MuonSubdetId::GEM or DetId(p.first).det() != DetId::Muon) {
2029  continue;
2030  }
2031  auto padRoll(GEMDetId(p.first).roll());
2032  if (debug) std::cout << "Candidate GEMPad: " << p.second << std::endl;
2033  // only pads in overlap are good for ME1A
2034  // if (part==ME1A and !isPadInOverlap(padRoll)) continue; /// eliminate this
2035  int pad_bx = (p.second).bx()+lct_central_bx;
2036  if (std::abs(alct_bx-pad_bx)>deltaBX) continue;
2037  if (alctRoll.first == -99 and alctRoll.second == -99) continue; //invalid region
2038  else if (alctRoll.first == -99 and !(padRoll <= alctRoll.second)) continue; // top of the chamber
2039  else if (alctRoll.second == -99 and !(padRoll >= alctRoll.first)) continue; // bottom of the chamber
2040  else if ((alctRoll.first != -99 and alctRoll.second != -99) and // center
2041  (alctRoll.first-1 > padRoll or padRoll > alctRoll.second+1)) continue;
2042  if (debug) std::cout << "++Matches! " << std::endl;
2043  result.push_back(p);
2044  if (first) return result;
2045  }
2046  return result;
2047 }
2048 
2049 
2052  enum ME11Part part, bool isCoPad, bool first)
2053 {
2055 
2056  // Fetch all (!) pads matching to ALCTs and CLCTs
2057  const auto& padsClct(matchingGEMPads(clct, pads, part, isCoPad, false));
2058  const auto& padsAlct(matchingGEMPads(alct, pads, part, isCoPad, false));
2059 
2060  const bool debug(false);
2061  if (debug) std::cout << "-----------------------------------------------------------------------"<<std::endl;
2062  if (debug) std::cout << "Finding common pads"<<std::endl;
2063  // Check if the pads overlap
2064  for (const auto& p : padsAlct){
2065  if (debug) std::cout<< "Candidate GEMPad matched to ALCT: " << p.first << " " << p.second << std::endl;
2066  for (const auto& q: padsClct){
2067  if (debug) std::cout<< "++Candidate GEMPad matched to CLCT: " << q.first << " " << q.second << std::endl;
2068  // look for exactly the same pads
2069  if ((p.first != q.first) or GEMPadDigi(p.second) != q.second) continue;
2070  if (debug) {
2071  if (isCoPad) std::cout << "++Matched copad" << GEMDetId(p.first) << " " << p.second << std::endl;
2072  else std::cout << "++Matched pad" << GEMDetId(p.first) << " " << p.second << std::endl;
2073  }
2074  result.push_back(p);
2075  if (first) return result;
2076  }
2077  }
2078  if (debug) std::cout << "-----------------------------------------------------------------------"<<std::endl;
2079  return result;
2080 }
2081 
2082 
2083 std::vector<GEMCoPadDigi>
2085 {
2086  return gemCoPadV;
2087 }
2088 
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:33
const unsigned theSector
T getParameter(std::string const &) const
std::map< int, std::pair< int, int > > cscHsToGemPadME1a_
std::vector< CSCCorrelatedLCTDigi > sortLCTsByQuality(int bx, enum ME11Part=ME1B)
void setALCT(const CSCALCTDigi &alct)
unsigned int clct_trig_enable
CSCChamber * chamber(unsigned endcap, unsigned station, unsigned sector, unsigned subsector, unsigned tcscid) const
Return the CSCChamber for a corresponding endcap/station/sector/subsector/trigger cscid...
static const int lut_wg_vs_hs_me1ag[48][2]
static bool sortByGEMDphi(const CSCCorrelatedLCTDigi &, const CSCCorrelatedLCTDigi &)
std::vector< CSCCorrelatedLCTDigi > readoutLCTs1a()
std::vector< CSCCorrelatedLCTDigi > readoutLCTs()
unsigned int match_trig_window_size
const unsigned theTrigChamber
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
unsigned int encodePatternGEM(const int ptn, const int highPt)
static const int GEM
Definition: MuonSubdetId.h:15
static const double lut_pt_vs_dphi_gemcsc[8][3]
int roll() const
Definition: GEMDetId.h:80
bool runME11ILT_
GEM-CSC integrated local algorithm.
const unsigned theEndcap
std::map< int, std::pair< int, int > > cscHsToGemPadME1b_
void clear()
clear this ALCT
Definition: CSCALCTDigi.cc:35
double maxEta
int deltaPad(int hs, int pad)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
int getStripType() const
return striptype
Definition: CSCCLCTDigi.h:39
int getBend() const
return bend
Definition: CSCCLCTDigi.h:42
unsigned int mpc_block_me1a
static const int lut_wg_vs_hs_me1b[48][2]
Definition: ME.h:11
GEMPadsBX matchingGEMPads(const CSCCLCTDigi &cLCT, const GEMPadsBX &pads=GEMPadsBX(), enum ME11Part=ME1B, bool isCopad=false, bool first=true)
CSCCorrelatedLCTDigi allLCTs1a[MAX_LCT_BINS][15][2]
const unsigned theStation
static CSCTriggerGeomManager * get()
void correlateLCTsGEM(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, CSCCorrelatedLCTDigi &lct1, CSCCorrelatedLCTDigi &lct2, int me, const GEMPadsBX &pads=GEMPadsBX(), const GEMPadsBX &copads=GEMPadsBX())
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
def unique(seq, keepstr=True)
Definition: tier0.py:24
int pad() const
Definition: GEMPadDigi.h:26
const unsigned theSubsector
int getBX() const
return BX
Definition: CSCCLCTDigi.h:51
std::map< int, std::pair< double, double > > gemRollToEtaLimits_
unsigned int encodePattern(const int ptn, const int highPt)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::unique_ptr< GEMCoPadProcessor > coPadProcessor
unsigned int tmb_l1a_window_size
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:30
unsigned int match_trig_enable
CSCCorrelatedLCTDigi constructLCTsGEM(const CSCALCTDigi &alct, const GEMPadDigi &gem, int me, bool oldDataFormat=false)
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< CSCCorrelatedLCTDigi > getLCTs1b()
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
int deltaRoll(int wg, int roll)
#define LogTrace(id)
const GEMSuperChamber * superChamber(GEMDetId id) const
Definition: GEMGeometry.cc:91
void printGEMTriggerPads(int minBX, int maxBx, bool iscopad=false)
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:48
std::vector< CSCCorrelatedLCTDigi > getLCTs1a()
static const int lut_wg_vs_hs_me1a[48][2]
Definition: DetId.h:18
int getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:33
#define debug
Definition: HDRShower.cc:19
int getAccelerator() const
Definition: CSCALCTDigi.h:37
int bx() const
Definition: GEMPadDigi.h:27
std::vector< CSCALCTDigi > alctV
int getPattern() const
return pattern
Definition: CSCCLCTDigi.h:36
part
Definition: HCALResponse.h:20
void retrieveGEMPads(const GEMPadDigiCollection *pads, unsigned id)
const GEMGeometry * gem_g
const GEMChamber * chamber(GEMDetId id) const
Definition: GEMGeometry.cc:95
unsigned int findQualityGEM(const CSCALCTDigi &aLCT, const GEMPadDigi &gem)
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:118
double b
Definition: hdecay.h:120
std::vector< GEMCoPadDigi > gemCoPadV
bool doesALCTCrossCLCT(CSCALCTDigi &a, CSCCLCTDigi &c, int me)
std::map< int, int > gemPadToCscHsME1a_
std::map< int, std::pair< int, int > > cscWgToGemRoll_
unsigned int alct_trig_enable
std::vector< CSCCorrelatedLCTDigi > readoutLCTs1b()
void createGEMRollEtaLUT(bool isEven)
std::unique_ptr< CSCAnodeLCTProcessor > alct
#define begin
Definition: vmac.h:30
double a
Definition: hdecay.h:121
std::vector< CSCCLCTDigi > clctV1b
std::vector< CSCCLCTDigi > clctV1a
std::unique_ptr< CSCCathodeLCTProcessor > clct
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc, const GEMPadDigiCollection *gemPads)
void clear()
clear this CLCT
Definition: CSCCLCTDigi.cc:58
CSCCorrelatedLCTDigi allLCTs1b[MAX_LCT_BINS][15][2]
std::map< int, int > gemPadToCscHsME1b_
int getKeyStrip() const
Definition: CSCCLCTDigi.h:65
std::unique_ptr< CSCCathodeLCTProcessor > clct1a
Detector det() const
get the detector field from this detid
Definition: DetId.h:35
void setTrknmb(const uint16_t number)
Set track number (1,2) after sorting LCTs.
void setCLCT(const CSCCLCTDigi &clct)
const CSCGeometry * csc_g
std::vector< GEMCoPadDigi > readoutCoPads()
int getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:45
void setGEM1(const GEMPadDigi &gem)
static int chamberFromTriggerLabels(int TriggerSector, int TriggerSubSector, int station, int TriggerCSCID)
static const double lut_wg_etaMin_etaMax_even[48][3]
static const double lut_wg_etaMin_etaMax_odd[48][3]
std::vector< GEMPadBX > GEMPadsBX
static bool sortByQuality(const CSCCorrelatedLCTDigi &, const CSCCorrelatedLCTDigi &)
void setConfigParameters(const CSCDBL1TPParameters *conf)
std::vector< CSCCorrelatedLCTDigi > sortLCTsByGEMDPhi(int bx, enum ME11Part=ME1B)