CMS 3D CMS Logo

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