CMS 3D CMS Logo

CSCMotherboardME21GEM.cc
Go to the documentation of this file.
8 #include <iomanip>
9 #include "boost/container/flat_set.hpp"
10 
11 const double CSCMotherboardME21GEM::lut_wg_eta_odd[112][2] = {
12 { 0,2.441},{ 1,2.435},{ 2,2.425},{ 3,2.414},{ 4,2.404},{ 5,2.394},{ 6,2.384},{ 7,2.374},
13 { 8,2.365},{ 9,2.355},{10,2.346},{11,2.336},{12,2.327},{13,2.317},{14,2.308},{15,2.299},
14 {16,2.290},{17,2.281},{18,2.273},{19,2.264},{20,2.255},{21,2.247},{22,2.238},{23,2.230},
15 {24,2.221},{25,2.213},{26,2.205},{27,2.197},{28,2.189},{29,2.181},{30,2.173},{31,2.165},
16 {32,2.157},{33,2.149},{34,2.142},{35,2.134},{36,2.127},{37,2.119},{38,2.112},{39,2.104},
17 {40,2.097},{41,2.090},{42,2.083},{43,2.075},{44,2.070},{45,2.059},{46,2.054},{47,2.047},
18 {48,2.041},{49,2.034},{50,2.027},{51,2.020},{52,2.014},{53,2.007},{54,2.000},{55,1.994},
19 {56,1.988},{57,1.981},{58,1.975},{59,1.968},{60,1.962},{61,1.956},{62,1.950},{63,1.944},
20 {64,1.937},{65,1.931},{66,1.924},{67,1.916},{68,1.909},{69,1.902},{70,1.895},{71,1.888},
21 {72,1.881},{73,1.875},{74,1.868},{75,1.861},{76,1.854},{77,1.848},{78,1.841},{79,1.835},
22 {80,1.830},{81,1.820},{82,1.815},{83,1.809},{84,1.803},{85,1.796},{86,1.790},{87,1.784},
23 {88,1.778},{89,1.772},{90,1.766},{91,1.760},{92,1.754},{93,1.748},{94,1.742},{95,1.736},
24 {96,1.731},{97,1.725},{98,1.719},{99,1.714},{100,1.708},{101,1.702},{102,1.697},{103,1.691},
25 {104,1.686},{105,1.680},{106,1.675},{107,1.670},{108,1.664},{109,1.659},{110,1.654},{111,1.648},
26 };
27 
28 const double CSCMotherboardME21GEM::lut_wg_eta_even[112][2] = {
29 { 0,2.412},{ 1,2.405},{ 2,2.395},{ 3,2.385},{ 4,2.375},{ 5,2.365},{ 6,2.355},{ 7,2.345},
30 { 8,2.335},{ 9,2.325},{10,2.316},{11,2.306},{12,2.297},{13,2.288},{14,2.279},{15,2.270},
31 {16,2.261},{17,2.252},{18,2.243},{19,2.234},{20,2.226},{21,2.217},{22,2.209},{23,2.200},
32 {24,2.192},{25,2.184},{26,2.175},{27,2.167},{28,2.159},{29,2.151},{30,2.143},{31,2.135},
33 {32,2.128},{33,2.120},{34,2.112},{35,2.105},{36,2.097},{37,2.090},{38,2.082},{39,2.075},
34 {40,2.068},{41,2.060},{42,2.053},{43,2.046},{44,2.041},{45,2.030},{46,2.025},{47,2.018},
35 {48,2.011},{49,2.005},{50,1.998},{51,1.991},{52,1.985},{53,1.978},{54,1.971},{55,1.965},
36 {56,1.958},{57,1.952},{58,1.946},{59,1.939},{60,1.933},{61,1.927},{62,1.921},{63,1.915},
37 {64,1.909},{65,1.902},{66,1.895},{67,1.887},{68,1.880},{69,1.873},{70,1.866},{71,1.859},
38 {72,1.853},{73,1.846},{74,1.839},{75,1.832},{76,1.826},{77,1.819},{78,1.812},{79,1.806},
39 {80,1.801},{81,1.792},{82,1.787},{83,1.780},{84,1.774},{85,1.768},{86,1.762},{87,1.756},
40 {88,1.750},{89,1.744},{90,1.738},{91,1.732},{92,1.726},{93,1.720},{94,1.714},{95,1.708},
41 {96,1.702},{97,1.697},{98,1.691},{99,1.685},{100,1.680},{101,1.674},{102,1.669},{103,1.663},
42 {104,1.658},{105,1.652},{106,1.647},{107,1.642},{108,1.636},{109,1.631},{110,1.626},{111,1.621},
43 };
44 
45 // LUT with bending angles of the GEM-CSC high efficiency patterns (98%)
46 // 1st index: pt value = {5,10,15,20,30,40}
47 // 2nd index: bending angle for odd numbered chambers
48 // 3rd index: bending angle for even numbered chambers
50  {3, 0.01832829, 0.01003643 },
51  {5, 0.01095490, 0.00631625 },
52  {7, 0.00786026, 0.00501017 },
53  {10, 0.00596349, 0.00414560 },
54  {15, 0.00462411, 0.00365550 },
55  {20, 0.00435298, 0.00361550 },
56  {30, 0.00465160, 0.00335700 },
57  {40, 0.00372145, 0.00366262 }
58 };
59 
61  unsigned sector, unsigned subsector,
62  unsigned chamber,
63  const edm::ParameterSet& conf) :
64  CSCMotherboard(endcap, station, sector, subsector, chamber, conf)
65 {
66  const edm::ParameterSet commonParams(conf.getParameter<edm::ParameterSet>("commonParam"));
67  runME21ILT_ = commonParams.getParameter<bool>("runME21ILT");
68 
69  if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError")
70  << "+++ Upgrade CSCMotherboardME21GEM constructed while isSLHC is not set! +++\n";
71 
72  const edm::ParameterSet me21tmbParams(conf.getParameter<edm::ParameterSet>("me21tmbSLHCGEM"));
73  const edm::ParameterSet coPadParams(conf.getParameter<edm::ParameterSet>("copadParam"));
74  coPadProcessor.reset( new GEMCoPadProcessor(endcap, station, 1, chamber, coPadParams) );
75 
76  // whether to not reuse CLCTs that were used by previous matching ALCTs
77  // in ALCT-to-CLCT algorithm
78  drop_used_clcts = me21tmbParams.getParameter<bool>("tmbDropUsedClcts");
79 
80  match_earliest_clct_me21_only = me21tmbParams.getParameter<bool>("matchEarliestClctME21Only");
81 
82  tmb_cross_bx_algo = me21tmbParams.getParameter<unsigned int>("tmbCrossBxAlgorithm");
83 
84  // maximum lcts per BX in ME2
85  max_me21_lcts = me21tmbParams.getParameter<unsigned int>("maxME21LCTs");
86 
88  for (unsigned int m=2; m<match_trig_window_size; m+=2)
89  {
90  pref[m-1] = pref[0] - m/2;
91  pref[m] = pref[0] + m/2;
92  }
93 
94  //----------------------------------------------------------------------------------------//
95 
96  // 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
97 
98  //----------------------------------------------------------------------------------------//
99 
100  // debug gem matching
101  debug_gem_matching = me21tmbParams.getParameter<bool>("debugMatching");
102  debug_luts = me21tmbParams.getParameter<bool>("debugLUTs");
103  debug_gem_dphi = me21tmbParams.getParameter<bool>("debugGEMDphi");
104 
105  // deltas used to match to GEM pads
106  maxDeltaBXPad_ = me21tmbParams.getParameter<int>("maxDeltaBXPad");
107  maxDeltaPadPadOdd_ = me21tmbParams.getParameter<int>("maxDeltaPadPadOdd");
108  maxDeltaPadPadEven_ = me21tmbParams.getParameter<int>("maxDeltaPadPadEven");
109  maxDeltaWg_ = me21tmbParams.getParameter<int>("maxDeltaWg");
110 
111  // deltas used to match to GEM coincidence pads
112  maxDeltaBXCoPad_ = me21tmbParams.getParameter<int>("maxDeltaBXCoPad");
113  maxDeltaPadCoPad_ = me21tmbParams.getParameter<int>("maxDeltaPadCoPad");
114 
115  // drop low quality stubs if they don't have GEMs
116  dropLowQualityCLCTsNoGEMs_ = me21tmbParams.getParameter<bool>("dropLowQualityCLCTsNoGEMs");
117  dropLowQualityALCTsNoGEMs_ = me21tmbParams.getParameter<bool>("dropLowQualityALCTsNoGEMs");
118 
119  // correct LCT timing with GEMs
120  correctLCTtimingWithGEM_ = me21tmbParams.getParameter<bool>("correctLCTtimingWithGEM");
121 
122  // build LCT from ALCT and GEM
123  buildLCTfromALCTandGEM_ = me21tmbParams.getParameter<bool>("buildLCTfromALCTandGEM");
124  buildLCTfromCLCTandGEM_ = me21tmbParams.getParameter<bool>("buildLCTfromCLCTandGEM");
125 
126  // LCT ghostbusting
127  doLCTGhostBustingWithGEMs_ = me21tmbParams.getParameter<bool>("doLCTGhostBustingWithGEMs");
128 
129  // use "old" or "new" dataformat for integrated LCTs?
130  useOldLCTDataFormat_ = me21tmbParams.getParameter<bool>("useOldLCTDataFormat");
131 
132  // promote ALCT-GEM pattern
133  promoteALCTGEMpattern_ = me21tmbParams.getParameter<bool>("promoteALCTGEMpattern");
134 
135  // promote ALCT-GEM quality
136  promoteALCTGEMquality_ = me21tmbParams.getParameter<bool>("promoteALCTGEMquality");
137  promoteCLCTGEMquality_ = me21tmbParams.getParameter<bool>("promoteCLCTGEMquality");
138 }
139 
141 {
142 }
143 
145 {
147 
148  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
149  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
150  for (int i=0;i<2;i++)
151  allLCTs[bx][mbx][i].clear();
152 
153  gemRollToEtaLimits_.clear();
154  cscWgToGemRoll_.clear();
155  gemPadToCscHs_.clear();
156  cscHsToGemPad_.clear();
157  pads_.clear();
158  coPads_.clear();
159 }
160 
161 void
163  const CSCComparatorDigiCollection* compdc,
164  const GEMPadDigiCollection* gemPads)
165 {
166  clear();
167 
168  if (!( alct and clct and runME21ILT_))
169  {
170  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
171  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
172  return;
173  }
174 
175  alct->run(wiredc); // run anodeLCT
176  clct->run(compdc); // run cathodeLCT
177  gemCoPadV = coPadProcessor->run(gemPads); // run copad processor in GE2/1
178 
179  bool gemGeometryAvailable(false);
180  if (gem_g != nullptr) {
181  if (infoV >= 0) edm::LogInfo("L1CSCTPEmulatorSetupInfo")
182  << "+++ run() called for GEM-CSC integrated trigger! +++ \n";
183  gemGeometryAvailable = true;
184  }
185 
186  // retrieve CSCChamber geometry
188  const CSCChamber* cscChamber(geo_manager->chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber));
189  const CSCDetId csc_id(cscChamber->id());
190 
191  if (runME21ILT_){
192 
193  // check for GE2/1 geometry
194  if ((not gemGeometryAvailable) or (gemGeometryAvailable and (gem_g->stations()).size()==2)) {
195  if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError")
196  << "+++ run() called for GEM-CSC integrated trigger without valid GE21 geometry! +++ \n";
197  return;
198  }
199 
200  // trigger geometry
201  const CSCLayer* keyLayer(cscChamber->layer(3));
202  const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry());
203 
204  // const bool isEven(csc_id%2==0);
205  const int region((theEndcap == 1) ? 1: -1);
206  const bool isEven(csc_id.chamber()%2==0);
207  const GEMDetId gem_id_long(region, 1, 2, 0, csc_id.chamber(), 0);
208  const GEMSuperChamber* gemChamberLong(gem_g->superChamber(gem_id_long));
209 
210  // LUT<roll,<etaMin,etaMax> >
212 
213  if (debug_luts){
214  std::cout<<"csc id "<< csc_id <<" "<< csc_id.rawId() << (isEven ? " even" : " odd") << " chamber" << csc_id.chamber()<<std::endl;
215  if (gemRollToEtaLimits_.size())
216  for(auto p : gemRollToEtaLimits_) {
217  std::cout << "pad "<< p.first << " min eta " << (p.second).first << " max eta " << (p.second).second << std::endl;
218  }
219  }
220 
221  // loop on all wiregroups to create a LUT <WG,rollMin,rollMax>
222  const int numberOfWG(keyLayerGeometry->numberOfWireGroups());
223  for (int i = 0; i< numberOfWG; ++i){
224  auto eta(isEven ? lut_wg_eta_even[i][1] : lut_wg_eta_odd[i][1]);
226  }
227  if (debug_luts){
228  for(auto p : cscWgToGemRoll_) {
229  std::cout << "WG "<< p.first << " GEM roll " << p.second << std::endl;
230  }
231  }
232 
233  auto randRoll(gemChamberLong->chamber(1)->etaPartition(2));
234  auto nStrips(keyLayerGeometry->numberOfStrips());
235  for (float i = 0; i< nStrips; i = i+0.5){
236  const LocalPoint lpCSC(keyLayerGeometry->topology()->localPosition(i));
237  const GlobalPoint gp(keyLayer->toGlobal(lpCSC));
238  const LocalPoint lpGEM(randRoll->toLocal(gp));
239  const int HS(i/0.5);
240  const bool edge(HS < 5 or HS > 155);
241  const float pad(edge ? -99 : randRoll->pad(lpGEM));
242  // HS are wrapped-around
243  cscHsToGemPad_[HS] = std::make_pair(std::floor(pad),std::ceil(pad));
244  }
245  if (debug_luts){
246  std::cout << "detId " << csc_id << std::endl;
247  for(auto p : cscHsToGemPad_) {
248  std::cout << "CSC HS "<< p.first << " GEM Pad low " << (p.second).first << " GEM Pad high " << (p.second).second << std::endl;
249  }
250  }
251 
252  // pick any roll
253  const int nGEMPads(randRoll->npads());
254  for (int i = 0; i< nGEMPads; ++i){
255  const LocalPoint lpGEM(randRoll->centreOfPad(i));
256  const GlobalPoint gp(randRoll->toGlobal(lpGEM));
257  const LocalPoint lpCSC(keyLayer->toLocal(gp));
258  const float strip(keyLayerGeometry->strip(lpCSC));
259  // HS are wrapped-around
260  gemPadToCscHs_[i] = (int) (strip - 0.25)/0.5;
261  }
262  if (debug_luts){
263  std::cout << "detId " << csc_id << std::endl;
264  for(auto p : gemPadToCscHs_) {
265  std::cout << "GEM Pad "<< p.first << " CSC HS : " << p.second << std::endl;
266  }
267  }
268 
269  //select correct scenario, even or odd
271 
272  // retrieve pads and copads in a certain BX window for this CSC
273  pads_.clear();
274  coPads_.clear();
275  retrieveGEMPads(gemPads, gem_id_long);
277  }
278 
279  int used_clct_mask[20];
280  for (int c=0;c<20;++c) used_clct_mask[c]=0;
281 
282  const bool hasPads(pads_.size()!=0);
283  const bool hasCoPads(hasPads and coPads_.size()!=0);
284 
285  // ALCT centric matching
286  for (int bx_alct = 0; bx_alct < CSCAnodeLCTProcessor::MAX_ALCT_BINS; bx_alct++)
287  {
288  if (alct->bestALCT[bx_alct].isValid())
289  {
290  const int bx_clct_start(bx_alct - match_trig_window_size/2);
291  const int bx_clct_stop(bx_alct + match_trig_window_size/2);
292  const int bx_copad_start(bx_alct - maxDeltaBXCoPad_);
293  const int bx_copad_stop(bx_alct + maxDeltaBXCoPad_);
294 
295  if (debug_gem_matching){
296  std::cout << "========================================================================" << std::endl;
297  std::cout << "ALCT-CLCT matching in ME2/1 chamber: " << cscChamber->id() << std::endl;
298  std::cout << "------------------------------------------------------------------------" << std::endl;
299  std::cout << "+++ Best ALCT Details: ";
300  alct->bestALCT[bx_alct].print();
301  std::cout << "+++ Second ALCT Details: ";
302  alct->secondALCT[bx_alct].print();
303 
304  printGEMTriggerPads(bx_clct_start, bx_clct_stop);
305 
306  std::cout << "------------------------------------------------------------------------" << std::endl;
307  std::cout << "Attempt ALCT-CLCT matching in ME2/1 in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl;
308  }
309 
310  // ALCT-to-CLCT
311  int nSuccesFulMatches = 0;
312  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
313  {
314  if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
315  if (drop_used_clcts and used_clct_mask[bx_clct]) continue;
316  if (clct->bestCLCT[bx_clct].isValid())
317  {
318  // clct quality
319  const int quality(clct->bestCLCT[bx_clct].getQuality());
320  // low quality ALCT
321  const bool lowQualityALCT(alct->bestALCT[bx_alct].getQuality() == 0);
322  // low quality ALCT or CLCT
323  const bool lowQuality(quality<4 or lowQualityALCT);
324  if (debug_gem_matching) std::cout << "++Valid ME21 CLCT: " << clct->bestCLCT[bx_clct] << std::endl;
325 
326  // pick the pad that corresponds
327  auto matchingPads(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_clct], false));
328  auto matchingCoPads(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_clct], true));
329  if (runME21ILT_ and dropLowQualityCLCTsNoGEMs_ and lowQuality and hasPads){
330  int nFound(matchingPads.size());
331  const bool clctInEdge(clct->bestCLCT[bx_clct].getKeyStrip() < 5 or clct->bestCLCT[bx_clct].getKeyStrip() > 155);
332  if (clctInEdge){
333  if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT in CSC chamber edge, don't care about GEM pads" << std::endl;
334  }
335  else {
336  if (nFound != 0){
337  if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT with " << nFound << " matching GEM trigger pads" << std::endl;
338  }
339  else {
340  if (debug_gem_matching) std::cout << "\tWarning: low quality CLCT without matching GEM trigger pad" << std::endl;
341  continue;
342  }
343  }
344  }
345 
346  // check timing
347  if (runME21ILT_ and correctLCTtimingWithGEM_){
348  int nFound(matchingCoPads.size());
349  if (nFound != 0 and bx_alct == 6 and bx_clct != 6){
350  if (debug_gem_matching) std::cout << "\tInfo: CLCT with incorrect timing" << std::endl;
351  continue;
352  }
353  }
354 
355  ++nSuccesFulMatches;
356 
357  int mbx = bx_clct-bx_clct_start;
358 
359  correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
360  clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct],
361  allLCTs[bx_alct][mbx][0], allLCTs[bx_alct][mbx][1], matchingPads, matchingCoPads);
362  if (debug_gem_matching) {
363  // if (infoV > 1) LogTrace("CSCMotherboard")
364  std::cout << "Successful ALCT-CLCT match in ME21: bx_alct = " << bx_alct
365  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
366  << "]; bx_clct = " << bx_clct << std::endl;
367  std::cout << "+++ Best CLCT Details: ";
368  clct->bestCLCT[bx_clct].print();
369  std::cout << "+++ Second CLCT Details: ";
370  clct->secondCLCT[bx_clct].print();
371  }
372  if (allLCTs[bx_alct][mbx][0].isValid()) {
373  used_clct_mask[bx_clct] += 1;
375  }
376  }
377  }
378 
379  // ALCT-to-GEM matching
380  int nSuccesFulGEMMatches = 0;
381  if (runME21ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandGEM_){
382  if (debug_gem_matching) std::cout << "++No valid ALCT-CLCT matches in ME21" << std::endl;
383  for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) {
384  if (not hasCoPads) {
385  continue;
386  }
387 
388  // find the best matching copad - first one
389  auto copads(matchingGEMPads(alct->bestALCT[bx_alct], coPads_[bx_gem], true));
390  if (debug_gem_matching) std::cout << "\t++Number of matching GEM CoPads in BX " << bx_alct << " : "<< copads.size() << std::endl;
391  if (copads.size()==0) {
392  continue;
393  }
394 
395  correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct],
396  copads.at(0).second, allLCTs[bx_alct][0][0], allLCTs[bx_alct][0][1]);
397  if (allLCTs[bx_alct][0][0].isValid()) {
398  ++nSuccesFulGEMMatches;
400  }
401  if (debug_gem_matching) {
402  std::cout << "Successful ALCT-GEM CoPad match in ME21: bx_alct = " << bx_alct << std::endl << std::endl;
403  std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
404  }
405  }
406  }
407 
408  if (debug_gem_matching) {
409  std::cout << "========================================================================" << std::endl;
410  std::cout << "Summary: " << std::endl;
411  if (nSuccesFulMatches>1)
412  std::cout << "Too many successful ALCT-CLCT matches in ME21: " << nSuccesFulMatches
413  << ", CSCDetId " << cscChamber->id()
414  << ", bx_alct = " << bx_alct
415  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
416  else if (nSuccesFulMatches==1)
417  std::cout << "1 successful ALCT-CLCT match in ME21: "
418  << " CSCDetId " << cscChamber->id()
419  << ", bx_alct = " << bx_alct
420  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
421  else if (nSuccesFulGEMMatches==1)
422  std::cout << "1 successful ALCT-GEM match in ME21: "
423  << " CSCDetId " << cscChamber->id()
424  << ", bx_alct = " << bx_alct
425  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
426  else
427  std::cout << "Unsuccessful ALCT-CLCT match in ME21: "
428  << "CSCDetId " << cscChamber->id()
429  << ", bx_alct = " << bx_alct
430  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl;
431  }
432  }
433  // at this point we have invalid ALCTs --> try GEM pad matching
434  else{
435  auto coPads(coPads_[bx_alct]);
436  if (runME21ILT_ and coPads.size() and buildLCTfromCLCTandGEM_) {
437  //const int bx_clct_start(bx_alct - match_trig_window_size/2);
438  //const int bx_clct_stop(bx_alct + match_trig_window_size/2);
439 
440  if (debug_gem_matching){
441  std::cout << "========================================================================" << std::endl;
442  // std::cout << "GEM-CLCT matching in ME2/1 chamber: " << cscChamber->id() << " in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl;
443  std::cout <<"GEM-CLCT matching in ME2/1 chamber: "<< cscChamber->id()<< "in bx:"<<bx_alct<<std::endl;
444  std::cout << "------------------------------------------------------------------------" << std::endl;
445  }
446  // GEM-to-CLCT
447  int nSuccesFulMatches = 0;
448  //for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++)
449  // {
450  // if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue;
451  if (drop_used_clcts and used_clct_mask[bx_alct]) continue;
452  if (clct->bestCLCT[bx_alct].isValid())
453  {
454  const int quality(clct->bestCLCT[bx_alct].getQuality());
455  // only use high-Q stubs for the time being
456  if (quality < 4) continue;
457 
458  ++nSuccesFulMatches;
459 
460  int mbx = std::abs(clct->bestCLCT[bx_alct].getBX()-bx_alct);
461  int bx_gem = (coPads[0].second).bx()+lct_central_bx;
462  correlateLCTsGEM(clct->bestCLCT[bx_alct], clct->secondCLCT[bx_alct], coPads[0].second, GEMDetId(coPads[0].first).roll(),
463  allLCTs[bx_gem][mbx][0], allLCTs[bx_gem][mbx][1]);
464  if (debug_gem_matching) {
465  // if (infoV > 1) LogTrace("CSCMotherboard")
466  std::cout << "Successful GEM-CLCT match in ME21: bx_alct = " << bx_alct <<std::endl;
467  //<< "; match window: [" << bx_clct_start << "; " << bx_clct_stop
468  //<< "]; bx_clct = " << bx_clct << std::endl;
469  std::cout << "+++ Best CLCT Details: ";
470  clct->bestCLCT[bx_alct].print();
471  std::cout << "+++ Second CLCT Details: ";
472  clct->secondCLCT[bx_alct].print();
473  }
474  if (allLCTs[bx_gem][mbx][0].isValid()) {
475  used_clct_mask[bx_alct] += 1;
477  }
478  }
479  }
480  }
481  }
482 
483  // reduction of nLCTs per each BX
484  for (int bx = 0; bx < MAX_LCT_BINS; bx++)
485  {
486  // counting
487  unsigned int n=0;
488  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
489  for (int i=0;i<2;i++)
490  {
491  int cbx = bx + mbx - match_trig_window_size/2;
492  if (allLCTs[bx][mbx][i].isValid())
493  {
494  ++n;
495  if (infoV > 0) LogDebug("CSCMotherboard")
496  << "LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs[bx][mbx][i]<<std::endl;
497  }
498  }
499 
500  // some simple cross-bx sorting algorithms
501  if (tmb_cross_bx_algo == 1 and (n>2))
502  {
503  n=0;
504  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
505  for (int i=0;i<2;i++)
506  {
507  if (allLCTs[bx][pref[mbx]][i].isValid())
508  {
509  n++;
510  if (n>2) allLCTs[bx][pref[mbx]][i].clear();
511  }
512  }
513 
514  n=0;
515  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
516  for (int i=0;i<2;i++)
517  {
518  int cbx = bx + mbx - match_trig_window_size/2;
519  if (allLCTs[bx][mbx][i].isValid())
520  {
521  n++;
522  if (infoV > 0) LogDebug("CSCMotherboard")
523  << "LCT"<<i+1<<" "<<bx<<"/"<<cbx<<": "<<allLCTs[bx][mbx][i]<<std::cout;
524  }
525  }
526  if (infoV > 0 and n>0) LogDebug("CSCMotherboard")
527  <<"bx "<<bx<<" nnLCT:"<<n<<" "<<n<<std::endl;
528  } // x-bx sorting
529  }
530 
531  bool first = true;
532  unsigned int n=0;
533  for (const auto& p : readoutLCTs()) {
534  if (debug_gem_matching and first){
535  std::cout << "========================================================================" << std::endl;
536  std::cout << "Counting the final LCTs" << std::endl;
537  std::cout << "========================================================================" << std::endl;
538  first = false;
539  std::cout << "tmb_cross_bx_algo: " << tmb_cross_bx_algo << std::endl;
540  }
541  n++;
542  if (debug_gem_matching)
543  std::cout << "LCT "<<n<<" " << p <<std::endl;
544  }
545 }
546 
547 
548 //readout LCTs
549 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME21GEM::readoutLCTs()
550 {
551  return getLCTs();
552 }
553 
554 //getLCTs when we use different sort algorithm
555 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME21GEM::getLCTs()
556 {
557  std::vector<CSCCorrelatedLCTDigi> result;
558  for (int bx = 0; bx < MAX_LCT_BINS; bx++) {
559  std::vector<CSCCorrelatedLCTDigi> tmpV;
560  if (tmb_cross_bx_algo == 2) {
561  tmpV = sortLCTsByQuality(bx);
562  result.insert(result.end(), tmpV.begin(), tmpV.end());
563  }
564  else if (tmb_cross_bx_algo == 3) {
565  tmpV = sortLCTsByGEMDPhi(bx);
566  result.insert(result.end(), tmpV.begin(), tmpV.end());
567  }
568  else {
569  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) {
570  for (int i=0;i<2;i++) {
571  if (allLCTs[bx][mbx][i].isValid()) {
572  result.push_back(allLCTs[bx][mbx][i]);
573  }
574  }
575  }
576  }
577  }
578  return result;
579 }
580 
581 //sort LCTs by Quality in each BX
582 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME21GEM::sortLCTsByQuality(int bx)
583 {
584  std::vector<CSCCorrelatedLCTDigi> LCTs;
585  LCTs.clear();
586  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
587  for (int i=0;i<2;i++)
588  if (allLCTs[bx][mbx][i].isValid())
589  LCTs.push_back(allLCTs[bx][mbx][i]);
590 
591  //std::cout<<"LCT before sorting in Bx:"<<bx<<std::endl;
592  //for (auto p : LCTs)
593  // std::cout<< p <<std::endl;
594  // return sorted vector with 2 highest quality LCTs
595  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByQuality);
596  if (LCTs.size()> max_me21_lcts) LCTs.erase(LCTs.begin()+max_me21_lcts, LCTs.end());
597  //std::cout<<"LCT after sorting by quality in BX:"<<bx<<std::endl;
598  //for (auto p : LCTs)
599  // std::cout<< p <<std::endl;
600  return LCTs;
601 }
602 
603 //sort LCTs by dphi in each BX
604 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME21GEM::sortLCTsByGEMDPhi(int bx)
605 {
606  std::vector<CSCCorrelatedLCTDigi> LCTs;
607  LCTs.clear();
608  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
609  for (int i=0;i<2;i++)
610  if (allLCTs[bx][mbx][i].isValid())
611  LCTs.push_back(allLCTs[bx][mbx][i]);
612 
613  // return sorted vector with 2 highest quality LCTs
614  std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByGEMDphi);
615  if (LCTs.size()> max_me21_lcts) LCTs.erase(LCTs.begin()+max_me21_lcts, LCTs.end());
616  return LCTs;
617 }
618 
619 
621  CSCALCTDigi secondALCT,
622  CSCCLCTDigi bestCLCT,
623  CSCCLCTDigi secondCLCT,
624  CSCCorrelatedLCTDigi& lct1,
625  CSCCorrelatedLCTDigi& lct2,
626  const GEMPadsBX& pads,
627  const GEMPadsBX& copads)
628 {
629  // check for pads
630  const int nPads(pads.size());
631  const int nCoPads(copads.size());
632  const bool hasPads(nPads!=0);
633  const bool hasCoPads(nCoPads!=0);
634 
635  bool anodeBestValid = bestALCT.isValid();
636  bool anodeSecondValid = secondALCT.isValid();
637  bool cathodeBestValid = bestCLCT.isValid();
638  bool cathodeSecondValid = secondCLCT.isValid();
639 
640  if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT;
641  if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT;
642  if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT;
643  if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT;
644 
645  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
646  // parameters.
647  if ((alct_trig_enable and bestALCT.isValid()) or
648  (clct_trig_enable and bestCLCT.isValid()) or
649  (match_trig_enable and bestALCT.isValid() and bestCLCT.isValid()))
650  {
651  lct1 = constructLCTsGEM(bestALCT, bestCLCT, hasPads, hasCoPads);
652  lct1.setTrknmb(1);
653  }
654 
655  if (((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) and
656  ((alct_trig_enable and secondALCT.isValid()) or
657  (clct_trig_enable and secondCLCT.isValid()) or
658  (match_trig_enable and secondALCT.isValid() and secondCLCT.isValid())))
659  {
660  lct2 = constructLCTsGEM(secondALCT, secondCLCT, hasPads, hasCoPads);
661  lct2.setTrknmb(2);
662  }
663 }
664 
665 
667  CSCALCTDigi secondALCT,
668  GEMPadDigi gemPad,
669  CSCCorrelatedLCTDigi& lct1,
670  CSCCorrelatedLCTDigi& lct2)
671 {
672  bool anodeBestValid = bestALCT.isValid();
673  bool anodeSecondValid = secondALCT.isValid();
674 
675  if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT;
676  if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT;
677 
678  if ((alct_trig_enable and bestALCT.isValid()) or
679  (match_trig_enable and bestALCT.isValid()))
680  {
681  lct1 = constructLCTsGEM(bestALCT, gemPad, useOldLCTDataFormat_);
682  lct1.setTrknmb(1);
683  // lct1.setGEMDPhi(0.0);
684  }
685 
686  if ((alct_trig_enable and secondALCT.isValid()) or
687  (match_trig_enable and secondALCT.isValid() and secondALCT != bestALCT))
688  {
689  lct2 = constructLCTsGEM(secondALCT, gemPad, useOldLCTDataFormat_);
690  lct2.setTrknmb(2);
691  // lct2.setGEMDPhi(0.0);
692  }
693 }
694 
695 
697  CSCCLCTDigi secondCLCT,
698  GEMPadDigi gemPad, int roll,
699  CSCCorrelatedLCTDigi& lct1,
700  CSCCorrelatedLCTDigi& lct2)
701 {
702  bool cathodeBestValid = bestCLCT.isValid();
703  bool cathodeSecondValid = secondCLCT.isValid();
704 
705  if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT;
706  if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT;
707 
708  if ((clct_trig_enable and bestCLCT.isValid()) or
709  (match_trig_enable and bestCLCT.isValid()))
710  {
711  lct1 = constructLCTsGEM(bestCLCT, gemPad, roll, useOldLCTDataFormat_);
712  lct1.setTrknmb(1);
713  }
714 
715  if ((clct_trig_enable and secondCLCT.isValid()) or
716  (match_trig_enable and secondCLCT.isValid() and secondCLCT != bestCLCT))
717  {
718  lct2 = constructLCTsGEM(secondCLCT, gemPad, roll, useOldLCTDataFormat_);
719  lct2.setTrknmb(2);
720  }
721 }
722 
723 
725  const GEMPadDigi& gem,
726  bool oldDataFormat)
727 {
728  if (oldDataFormat){
729  // CLCT pattern number - set it to a highest value
730  // hack to get LCTs in the CSCTF
731  unsigned int pattern = promoteALCTGEMpattern_ ? 10 : 0;
732 
733  // LCT quality number - set it to a very high value
734  // hack to get LCTs in the CSCTF
735  unsigned int quality = promoteALCTGEMquality_ ? 14 : 11;
736 
737  // Bunch crossing
738  int bx = alct.getBX();
739 
740  // get keyStrip from LUT
741  int keyStrip = gemPadToCscHs_[gem.pad()];
742 
743  // get wiregroup from ALCT
744  int wg = alct.getKeyWG();
745 
746  // construct correlated LCT; temporarily assign track number of 0.
747  return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber);
748  }
749  else {
750  // CLCT pattern number - no pattern
751  unsigned int pattern = 0;
752 
753  // LCT quality number
754  unsigned int quality = 1;
755 
756  // Bunch crossing
757  int bx = gem.bx() + lct_central_bx;
758 
759  // get keyStrip from LUT
760  int keyStrip = gemPadToCscHs_[gem.pad()];
761  // get wiregroup from ALCT
762  int wg = alct.getKeyWG();
763 
764  // construct correlated LCT; temporarily assign track number of 0.
765  return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber);
766  }
767 }
768 
770  const GEMPadDigi& gem, int roll,
771  bool oldDataFormat)
772 {
773  if (oldDataFormat){
774  // CLCT pattern number - for the time being, do not include GEMs in the pattern
775  unsigned int pattern = encodePattern(clct.getPattern(), clct.getStripType());
776 
777  // LCT quality number - dummy quality
778  unsigned int quality = promoteCLCTGEMquality_ ? 14 : 11;
779 
780  // Bunch crossing: pick GEM bx
781  int bx = gem.bx() + lct_central_bx;
782 
783  // pick a random WG in the roll range
784  int wg(20);
785 
786  // construct correlated LCT; temporarily assign track number of 0.
787  return CSCCorrelatedLCTDigi(0, 1, quality, wg, clct.getKeyStrip(), pattern, clct.getBend(), bx, 0, 0, 0, theTrigChamber);
788  }
789  else {
790  // CLCT pattern number - no pattern
791  unsigned int pattern = 0;//encodePatternGEM(clct.getPattern(), clct.getStripType());
792 
793  // LCT quality number - dummy quality
794  unsigned int quality = 5;//findQualityGEM(alct, gem);
795 
796  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
797  int bx = gem.bx() + lct_central_bx;;
798 
799  // ALCT WG
800  int wg(0);
801 
802  // construct correlated LCT; temporarily assign track number of 0.
803  return CSCCorrelatedLCTDigi(0, 1, quality, wg, 0, pattern, 0, bx, 0, 0, 0, theTrigChamber);
804  }
805 }
806 
807 
809  bool hasPad, bool hasCoPad)
810 {
811  // CLCT pattern number
812  unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType());
813 
814  // LCT quality number
815  unsigned int quality = findQualityGEM(aLCT, cLCT, hasPad, hasCoPad);
816 
817  // Bunch crossing: get it from cathode LCT if anode LCT is not there.
818  int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX();
819 
820  // construct correlated LCT; temporarily assign track number of 0.
821  int trknmb = 0;
822  CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(),
823  cLCT.getKeyStrip(), pattern, cLCT.getBend(),
824  bx, 0, 0, 0, theTrigChamber);
825  return thisLCT;
826 }
827 
828 
829 unsigned int CSCMotherboardME21GEM::findQualityGEM(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT,
830  bool hasPad, bool hasCoPad)
831 {
832 
833  /*
834  Same LCT quality definition as standard LCTs
835  c4 takes GEMs into account!!!
836  */
837 
838  unsigned int quality = 0;
839 
840  if (!isTMB07) {
841  bool isDistrip = (cLCT.getStripType() == 0);
842 
843  if (aLCT.isValid() && !(cLCT.isValid())) { // no CLCT
844  if (aLCT.getAccelerator()) {quality = 1;}
845  else {quality = 3;}
846  }
847  else if (!(aLCT.isValid()) && cLCT.isValid()) { // no ALCT
848  if (isDistrip) {quality = 4;}
849  else {quality = 5;}
850  }
851  else if (aLCT.isValid() && cLCT.isValid()) { // both ALCT and CLCT
852  if (aLCT.getAccelerator()) {quality = 2;} // accelerator muon
853  else { // collision muon
854  // CLCT quality is, in fact, the number of layers hit, so subtract 3
855  // to get quality analogous to ALCT one.
856  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
857  if (sumQual < 1 || sumQual > 6) {
858  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
859  << "+++ findQuality: sumQual = " << sumQual << "+++ \n";
860  }
861  if (isDistrip) { // distrip pattern
862  if (sumQual == 2) {quality = 6;}
863  else if (sumQual == 3) {quality = 7;}
864  else if (sumQual == 4) {quality = 8;}
865  else if (sumQual == 5) {quality = 9;}
866  else if (sumQual == 6) {quality = 10;}
867  }
868  else { // halfstrip pattern
869  if (sumQual == 2) {quality = 11;}
870  else if (sumQual == 3) {quality = 12;}
871  else if (sumQual == 4) {quality = 13;}
872  else if (sumQual == 5) {quality = 14;}
873  else if (sumQual == 6) {quality = 15;}
874  }
875  }
876  }
877  }
878 #ifdef OLD
879  else {
880  // Temporary definition, used until July 2008.
881  // First if statement is fictitious, just to help the CSC TF emulator
882  // handle such cases (one needs to make sure they will be accounted for
883  // in the new quality definition.
884  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
885  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
886  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
887  else quality = 0; // both absent; should never happen.
888  }
889  else {
890  // Sum of ALCT and CLCT quality bits. CLCT quality is, in fact, the
891  // number of layers hit, so subtract 3 to put it to the same footing as
892  // the ALCT quality.
893  int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3);
894  if (sumQual < 1 || sumQual > 6) {
895  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
896  << "+++ findQuality: Unexpected sumQual = " << sumQual << "+++\n";
897  }
898 
899  // LCT quality is basically the sum of ALCT and CLCT qualities, but split
900  // in two groups depending on the CLCT pattern id (higher quality for
901  // straighter patterns).
902  int offset = 0;
903  if (cLCT.getPattern() <= 7) offset = 4;
904  else offset = 9;
905  quality = offset + sumQual;
906  }
907  }
908 #endif
909  else {
910  // 2008 definition.
911  if (!(aLCT.isValid()) || !(cLCT.isValid())) {
912  if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT
913  else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT
914  else quality = 0; // both absent; should never happen.
915  }
916  else {
917  const int pattern(cLCT.getPattern());
918  if (pattern == 1) quality = 3; // layer-trigger in CLCT
919  else {
920  // ALCT quality is the number of layers hit minus 3.
921  // CLCT quality is the number of layers hit.
922  int n_gem = 0;
923  if (hasPad) n_gem = 1;
924  if (hasCoPad) n_gem = 2;
925  const bool a4((aLCT.getQuality() >= 1) or (aLCT.getQuality() >= 0 and n_gem >=1));
926  const bool c4((cLCT.getQuality() >= 4) or (cLCT.getQuality() >= 3 and n_gem>=1));
927  // quality = 4; "reserved for low-quality muons in future"
928  if (!a4 && !c4) quality = 5; // marginal anode and cathode
929  else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode
930  else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode
931  else if ( a4 && c4) {
932  if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT
933  else {
934  // quality = 9; "reserved for HQ muons with future patterns
935  // quality = 10; "reserved for HQ muons with future patterns
936  if (pattern == 2 || pattern == 3) quality = 11;
937  else if (pattern == 4 || pattern == 5) quality = 12;
938  else if (pattern == 6 || pattern == 7) quality = 13;
939  else if (pattern == 8 || pattern == 9) quality = 14;
940  else if (pattern == 10) quality = 15;
941  else {
942  if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues")
943  << "+++ findQuality: Unexpected CLCT pattern id = "
944  << pattern << "+++\n";
945  }
946  }
947  }
948  }
949  }
950  }
951  return quality;
952 }
953 
954 
955 std::map<int,std::pair<double,double> >
957 {
958  std::map<int,std::pair<double,double> > result;
959 
960  auto chamber(gem_g->chamber(GEMDetId(1,1,2,1,1,0)));
961  if (chamber==nullptr) return result;
962 
963  for(int i = 1; i<= chamber->nEtaPartitions(); ++i){
964  auto roll(chamber->etaPartition(i));
965  if (roll==nullptr) continue;
966  const float half_striplength(roll->specs()->specificTopology().stripLength()/2.);
967  const LocalPoint lp_top(0., half_striplength, 0.);
968  const LocalPoint lp_bottom(0., -half_striplength, 0.);
969  const GlobalPoint gp_top(roll->toGlobal(lp_top));
970  const GlobalPoint gp_bottom(roll->toGlobal(lp_bottom));
971  //result[i] = std::make_pair(floorf(gp_top.eta() * 100) / 100, ceilf(gp_bottom.eta() * 100) / 100);
972  result[i] = std::make_pair(gp_top.eta(), gp_bottom.eta());
973  }
974  return result;
975 }
976 
978 {
979  auto superChamber(gem_g->superChamber(id));
980  for (const auto& ch : superChamber->chambers()) {
981  for (const auto& roll : ch->etaPartitions()) {
982  GEMDetId roll_id(roll->id());
983  auto pads_in_det = gemPads->get(roll_id);
984  for (auto pad = pads_in_det.first; pad != pads_in_det.second; ++pad) {
985  auto id_pad = std::make_pair(roll_id, *pad);
986  const int bx_shifted(lct_central_bx + pad->bx());
987  for (int bx = bx_shifted - maxDeltaBXPad_;bx <= bx_shifted + maxDeltaBXPad_; ++bx) {
988  pads_[bx].push_back(id_pad);
989  }
990  }
991  }
992  }
993 }
994 
996 {
997  for (const auto& copad: gemCoPadV){
998  if (copad.first().bx() != lct_central_bx) continue;
999  coPads_[copad.bx(1)].push_back(std::make_pair(copad.roll(), copad.first()));
1000  coPads_[copad.bx(1)].push_back(std::make_pair(copad.roll(), copad.second()));
1001  }
1002 }
1003 
1004 void CSCMotherboardME21GEM::printGEMTriggerPads(int bx_start, int bx_stop, bool iscopad)
1005 {
1006  // pads or copads?
1007  auto thePads(!iscopad ? pads_ : coPads_ );
1008  const bool hasPads(thePads.size()!=0);
1009 
1010  std::cout << "------------------------------------------------------------------------" << std::endl;
1011  bool first = true;
1012  for (int bx = bx_start; bx <= bx_stop; bx++) {
1013  // print only the pads for the central BX
1014  //if (bx!=lct_central_bx and iscopad) continue;
1015  std::vector<std::pair<unsigned int, const GEMPadDigi> > in_pads = thePads[bx];
1016  if (first) {
1017  if (!iscopad) std::cout << "* GEM trigger pads: " << std::endl;
1018  else std::cout << "* GEM trigger coincidence pads: " << std::endl;
1019  }
1020  first = false;
1021  if (!iscopad) std::cout << "N(pads) BX " << bx << " : " << in_pads.size() << std::endl;
1022  else std::cout << "N(copads) BX " << bx << " : " << in_pads.size() << std::endl;
1023  if (hasPads){
1024  for (const auto& pad : in_pads){
1025  if (DetId(pad.first).subdetId() != MuonSubdetId::GEM or DetId(pad.first).det() != DetId::Muon) {
1026  continue;
1027  }
1028  auto roll_id(GEMDetId(pad.first));
1029  std::cout << "\tdetId " << pad.first << " " << roll_id << ", pad = " << pad.second.pad() << ", BX = " << pad.second.bx() + 6 << std::endl;
1030  }
1031  }
1032  else
1033  break;
1034  }
1035 }
1036 
1037 
1040 {
1042 
1043  // fetch the low and high pad edges for the long superchambers
1044  int deltaPad(isCoPad ? maxDeltaPadCoPad_ : maxDeltaPadPad_);
1045  int deltaBX(isCoPad ? maxDeltaBXCoPad_ : maxDeltaBXPad_);
1046  int clct_bx = clct.getBX();
1047  const int lowPad(cscHsToGemPad_[clct.getKeyStrip()].first);
1048  const int highPad(cscHsToGemPad_[clct.getKeyStrip()].second);
1049  const bool debug(false);
1050  if (debug) std::cout << "lowpad " << lowPad << " highpad " << highPad << " delta pad " << deltaPad <<std::endl;
1051  for (const auto& p: pads){
1052  if (DetId(p.first).subdetId() != MuonSubdetId::GEM or DetId(p.first).det() != DetId::Muon) {
1053  continue;
1054  }
1055  auto padRoll((p.second).pad());
1056  int pad_bx = (p.second).bx()+lct_central_bx;
1057  if (debug) std::cout << "padRoll " << padRoll << std::endl;
1058  if (std::abs(clct_bx-pad_bx)>deltaBX) continue;
1059  if (std::abs(lowPad - padRoll) <= deltaPad or std::abs(padRoll - highPad) <= deltaPad){
1060  if (debug) std::cout << "++Matches! " << std::endl;
1061  result.push_back(p);
1062  if (first) return result;
1063  }
1064  }
1065  return result;
1066 }
1067 
1068 
1071 {
1073  int deltaBX(isCoPad ? maxDeltaBXCoPad_ : maxDeltaBXPad_);
1074  int alct_bx = alct.getBX();
1075  int Wg = alct.getKeyWG();
1076  std::vector<int> Rolls;
1077  Rolls.push_back(cscWgToGemRoll_[Wg]);
1078  if (Wg>=maxDeltaWg_ && cscWgToGemRoll_[Wg] != cscWgToGemRoll_[Wg-maxDeltaWg_])
1079  Rolls.push_back(cscWgToGemRoll_[Wg-maxDeltaWg_]);
1080  if ((unsigned int)(Wg+maxDeltaWg_)<cscWgToGemRoll_.size() && cscWgToGemRoll_[Wg] != cscWgToGemRoll_[Wg+maxDeltaWg_])
1081  Rolls.push_back(cscWgToGemRoll_[Wg+maxDeltaWg_]);
1082 
1083  const bool debug(false);
1084  if (debug) std::cout << "ALCT keyWG " << alct.getKeyWG() << std::endl;
1085  for (const auto& alctRoll : Rolls)
1086  {
1087  if (debug) std::cout <<"roll " << alctRoll << std::endl;
1088  for (const auto& p: pads){
1089  if (DetId(p.first).subdetId() != MuonSubdetId::GEM or DetId(p.first).det() != DetId::Muon) {
1090  continue;
1091  }
1092  auto padRoll(GEMDetId(p.first).roll());
1093  int pad_bx = (p.second).bx()+lct_central_bx;
1094  if (debug) std::cout<<"Detid "<< GEMDetId(p.first) <<" "<< p.second<<std::endl;
1095  if (debug) std::cout << "Candidate ALCT: " << padRoll << std::endl;
1096  if (std::abs(alct_bx-pad_bx)>deltaBX) continue;
1097  if (alctRoll != padRoll) continue;
1098  if (debug) std::cout << "++Matches! " << std::endl;
1099  result.push_back(p);
1100  if (first) return result;
1101  }
1102  }
1103  return result;
1104 }
1105 
1106 
1109  bool isCoPad, bool first)
1110 {
1112 
1113  // Fetch all (!) pads matching to ALCTs and CLCTs
1114  auto padsClct(matchingGEMPads(clct, pads, isCoPad, false));
1115  auto padsAlct(matchingGEMPads(alct, pads, isCoPad, false));
1116 
1117  const bool debug(false);
1118  if (debug) std::cout << "-----------------------------------------------------------------------"<<std::endl;
1119  // Check if the pads overlap
1120  for (const auto& p : padsAlct){
1121  if (debug) std::cout<< "Candidate ALCT: " << p.first << " " << p.second << std::endl;
1122  for (const auto& q: padsClct){
1123  if (debug) std::cout<< "++Candidate CLCT: " << q.first << " " << q.second << std::endl;
1124  // look for exactly the same pads
1125  if ((p.first != q.first) or p.second != q.second) continue;
1126  if (debug) std::cout << "++Matches! " << std::endl;
1127  result.push_back(p);
1128  if (first) return result;
1129  }
1130  }
1131  if (debug) std::cout << "-----------------------------------------------------------------------"<<std::endl;
1132  return result;
1133 }
1134 
1135 
1137 {
1138  int result = -99;
1139  for(auto p : gemRollToEtaLimits_) {
1140  const float minEta((p.second).first);
1141  const float maxEta((p.second).second);
1142  if (minEta <= eta and eta <= maxEta) {
1143  result = p.first;
1144  break;
1145  }
1146  }
1147  return result;
1148 }
1149 
1150 
1151 std::vector<GEMCoPadDigi> CSCMotherboardME21GEM::readoutCoPads()
1152 {
1153  return gemCoPadV;
1154 }
#define LogDebug(id)
int getQuality() const
return quality of a pattern (number of layers hit!)
Definition: CSCCLCTDigi.h:33
size
Write out results.
std::vector< GEMCoPadDigi > readoutCoPads()
const unsigned theSector
T getParameter(std::string const &) const
std::vector< CSCCorrelatedLCTDigi > getLCTs()
GEMPadsBX matchingGEMPads(const CSCCLCTDigi &cLCT, const GEMPadsBX &pads=GEMPadsBX(), bool isCopad=false, bool first=true)
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...
unsigned int findQualityGEM(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT, bool hasPad, bool hasCoPad)
std::unique_ptr< GEMCoPadProcessor > coPadProcessor
static bool sortByGEMDphi(const CSCCorrelatedLCTDigi &, const CSCCorrelatedLCTDigi &)
unsigned int match_trig_window_size
const unsigned theTrigChamber
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
std::map< int, std::pair< double, double > > gemRollToEtaLimits_
static const int GEM
Definition: MuonSubdetId.h:15
int roll() const
Definition: GEMDetId.h:80
const unsigned theEndcap
double maxEta
std::vector< CSCCorrelatedLCTDigi > sortLCTsByQuality(int bx)
int getStripType() const
return striptype
Definition: CSCCLCTDigi.h:39
int deltaPad(int hs, int pad)
int getBend() const
return bend
Definition: CSCCLCTDigi.h:42
const unsigned theStation
void retrieveGEMPads(const GEMPadDigiCollection *pads, unsigned id)
static CSCTriggerGeomManager * get()
static const double lut_wg_eta_odd[112][2]
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
int pad() const
Definition: GEMPadDigi.h:26
const unsigned theSubsector
int getBX() const
return BX
Definition: CSCCLCTDigi.h:51
unsigned int encodePattern(const int ptn, const int highPt)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< GEMPadBX > GEMPadsBX
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:30
unsigned int match_trig_enable
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
std::map< int, std::pair< double, double > > createGEMRollEtaLUT()
const GEMSuperChamber * superChamber(GEMDetId id) const
Definition: GEMGeometry.cc:91
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:48
Definition: DetId.h:18
int getQuality() const
return quality of a pattern
Definition: CSCALCTDigi.h:33
#define debug
Definition: HDRShower.cc:19
static const double lut_pt_vs_dphi_gemcsc[8][3]
int getAccelerator() const
Definition: CSCALCTDigi.h:37
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc, const GEMPadDigiCollection *gemPads)
std::map< int, std::pair< int, int > > cscHsToGemPad_
int bx() const
Definition: GEMPadDigi.h:27
int getPattern() const
return pattern
Definition: CSCCLCTDigi.h:36
const GEMChamber * chamber(GEMDetId id) const
Definition: GEMGeometry.cc:95
std::map< int, int > gemPadToCscHs_
CSCCorrelatedLCTDigi allLCTs[MAX_LCT_BINS][15][2]
const GEMGeometry * gem_g
unsigned int alct_trig_enable
std::vector< GEMCoPadDigi > gemCoPadV
std::unique_ptr< CSCAnodeLCTProcessor > alct
void printGEMTriggerPads(int minBX, int maxBx, bool iscopad=false)
CSCCorrelatedLCTDigi constructLCTsGEM(const CSCALCTDigi &alct, const GEMPadDigi &gem, bool oldDataFormat=false)
std::vector< CSCCorrelatedLCTDigi > sortLCTsByGEMDPhi(int bx)
std::unique_ptr< CSCCathodeLCTProcessor > clct
std::vector< CSCCorrelatedLCTDigi > readoutLCTs()
const std::vector< const GEMStation * > & stations() const
Return a vector of all GEM stations.
Definition: GEMGeometry.cc:47
CSCMotherboardME21GEM(unsigned endcap, unsigned station, unsigned sector, unsigned subsector, unsigned chamber, const edm::ParameterSet &conf)
int getKeyStrip() const
Definition: CSCCLCTDigi.h:65
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 correlateLCTsGEM(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, GEMPadDigi gemPad, CSCCorrelatedLCTDigi &lct1, CSCCorrelatedLCTDigi &lct2)
std::map< int, int > cscWgToGemRoll_
int getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:45
static bool sortByQuality(const CSCCorrelatedLCTDigi &, const CSCCorrelatedLCTDigi &)
static const double lut_wg_eta_even[112][2]