CMS 3D CMS Logo

CSCMotherboardME11.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // Class: CSCMotherboardME11
4 //
5 // Description:
6 // Extended CSCMotherboard for ME11 to handle ME1a and ME1b separately
7 //
8 // Author List: Vadim Khotilovich 12 May 2009
9 //
10 //
11 //-----------------------------------------------------------------------------
12 
14 
16  unsigned sector, unsigned subsector,
17  unsigned chamber,
18  const edm::ParameterSet& conf) :
19  CSCUpgradeMotherboard(endcap, station, sector, subsector, chamber, conf)
20 {
21  if (!isSLHC_) edm::LogError("CSCMotherboardME11|ConfigError")
22  << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC_ is not set! +++\n";
23 
24  cscTmbLUT_.reset(new CSCMotherboardLUTME11());
25 
26  // ignore unphysical ALCT-CLCT matches
27  ignoreAlctCrossClct = tmbParams_.getParameter<bool>("ignoreAlctCrossClct");
28 }
29 
30 
33 {
34  if (!isSLHC_) edm::LogError("CSCMotherboardME11|ConfigError")
35  << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC_ is not set! +++\n";
36 }
37 
38 
40 {
41 }
42 
43 
45 {
47 }
48 
49 // Set configuration parameters obtained via EventSetup mechanism.
51 {
52  alctProc->setConfigParameters(conf);
53  clctProc->setConfigParameters(conf);
54  // No config. parameters in DB for the TMB itself yet.
55 }
56 
57 
59  const CSCComparatorDigiCollection* compdc)
60 {
61  clear();
62 
63  // Check for existing processors
64  if (!( alctProc && clctProc && isSLHC_))
65  {
66  if (infoV >= 0) edm::LogError("CSCMotherboardME11|SetupError")
67  << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n";
68  return;
69  }
70 
71  alctProc->setCSCGeometry(cscGeometry_);
72  clctProc->setCSCGeometry(cscGeometry_);
73 
74  alctV = alctProc->run(wiredc); // run anodeLCT
75  clctV = clctProc->run(compdc); // run cathodeLCT
76 
77  // if there are no ALCTs and no CLCTs, it does not make sense to run this TMB
78  if (alctV.empty() and clctV.empty()) return;
79 
80  int used_alct_mask[20];
81  int used_clct_mask[20];
82  for (int b=0;b<20;b++)
83  used_alct_mask[b] = used_clct_mask[b] = 0;
84 
85  // CLCT-centric CLCT-to-ALCT matching
86  if (clct_to_alct) {
87 
88  for (int bx_clct = 0; bx_clct < CSCConstants::MAX_CLCT_TBINS; bx_clct++) {
89 
90  if (clctProc->bestCLCT[bx_clct].isValid()) {
91  bool is_matched = false;
92  const int bx_alct_start = bx_clct - match_trig_window_size/2 + alctClctOffset_;
93  const int bx_alct_stop = bx_clct + match_trig_window_size/2 + alctClctOffset_;
94  for (int bx_alct = bx_alct_start; bx_alct <= bx_alct_stop; bx_alct++) {
95 
96  if (bx_alct < 0 || bx_alct >= CSCConstants::MAX_ALCT_TBINS) continue;
97  if (drop_used_alcts && used_alct_mask[bx_alct]) continue;
98  if (alctProc->bestALCT[bx_alct].isValid()) {
99  if (infoV > 1) LogTrace("CSCMotherboardME11")
100  << "Successful CLCT-ALCT match in ME11: bx_clct = " << bx_clct
101  << "; match window: [" << bx_alct_start << "; " << bx_alct_stop
102  << "]; bx_alct = " << bx_alct;
103  int mbx = bx_alct_stop - bx_alct;
104  correlateLCTsME11(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
105  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
106  allLCTs(bx_alct,mbx,0), allLCTs(bx_alct,mbx,1));
107  if (allLCTs(bx_alct,mbx,0).isValid()) {
108  used_alct_mask[bx_alct] += 1;
109  if (match_earliest_alct_only) break;
110  }
111  }
112  }
113  // Do not report CLCT-only LCT for ME11
114  if (!is_matched) {
115  if (infoV > 1) LogTrace("CSCMotherboard")
116  << "Unsuccessful ALCT-CLCT match (CLCT only): bx_clct = "
117  << bx_clct <<" first CLCT "<< clctProc->bestCLCT[bx_clct]
118  <<"; match window: [" << bx_alct_start
119  << "; " << bx_alct_stop << "]";
120  }
121  }
122  } // end of CLCT-centric matching
123 
124  // ALCT-centric ALCT-to-CLCT matching
125  }
126  else {
127  for (int bx_alct = 0; bx_alct < CSCConstants::MAX_ALCT_TBINS; bx_alct++) {
128  if (alctProc->bestALCT[bx_alct].isValid()) {
129  const int bx_clct_start = bx_alct - match_trig_window_size/2 - alctClctOffset_;
130  const int bx_clct_stop = bx_alct + match_trig_window_size/2 - alctClctOffset_;
131 
132  // matching in ME11
133  bool is_matched = false;
134  for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) {
135  if (bx_clct < 0 || bx_clct >= CSCConstants::MAX_CLCT_TBINS) continue;
136  if (drop_used_clcts && used_clct_mask[bx_clct]) continue;
137  if (clctProc->bestCLCT[bx_clct].isValid()) {
138  if (infoV > 1) LogTrace("CSCMotherboardME11")
139  << "Successful ALCT-CLCT match in ME11: bx_alct = " << bx_alct
140  << "; match window: [" << bx_clct_start << "; " << bx_clct_stop
141  << "]; bx_clct = " << bx_clct;
142  int mbx = bx_clct-bx_clct_start;
143  correlateLCTsME11(alctProc->bestALCT[bx_alct], alctProc->secondALCT[bx_alct],
144  clctProc->bestCLCT[bx_clct], clctProc->secondCLCT[bx_clct],
145  allLCTs(bx_alct,mbx,0), allLCTs(bx_alct,mbx,1));
146  if (allLCTs(bx_alct,mbx,0).isValid()) {
147  is_matched = true;
148  used_clct_mask[bx_clct] += 1;
149  if (match_earliest_clct_only) break;
150  }
151  }
152  }
153  if (!is_matched) {
154  if (infoV > 1) LogTrace("CSCMotherboard")
155  << "Unsuccessful ALCT-CLCT match (ALCT only): bx_alct = "
156  << bx_alct <<" first ALCT "<< alctProc->bestALCT[bx_alct]
157  << "; match window: [" << bx_clct_start
158  << "; " << bx_clct_stop << "]";
159  }
160  }
161  } // end of ALCT-centric matching
162  }
163 
164  // reduction of nLCTs per each BX
165  //add similar cross bx algorithm to standard TMB in next step
166  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
167  // counting
168  unsigned int nlct=0;
169  unsigned int nbx = 0;
170  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++){
171  bool hasLCT = false;
172  for (int i=0;i<CSCConstants::MAX_LCTS_PER_CSC;i++) {
173  if (allLCTs(bx,mbx,i).isValid()) {
174  nlct++;
175  hasLCT = true;
176  if (infoV > 0) {
177  LogDebug("CSCMotherboardME11") << "LCT"<<i+1<<" "<<bx<<"/"
178  <<bx + mbx - match_trig_window_size/2<<": "<<allLCTs(bx,mbx,i);
179  }
180  }
181  }
182  if (hasLCT) nbx++;
183  }
184  if (infoV > 0 && nlct>0) LogDebug("CSCMotherboardME11") <<"bx "<<bx<<" nLCT: "<<nlct <<" total mbx with LCTs "<< nbx;
185 
186  // some simple cross-bx sorting algorithms
187  if (tmb_cross_bx_algo == 1 and (nlct>2 or nbx>1)) {
188  nbx = 0;
189  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) {
190  nlct = 0;
191  bool hasLCT = false;
192  for (int i=0;i<CSCConstants::MAX_LCTS_PER_CSC;i++) {
193  if (allLCTs(bx,pref[mbx],i).isValid()) {
194  nlct++;
195  hasLCT = true;
196  if (nlct > CSCConstants::MAX_LCTS_PER_CSC or nbx >0 ) allLCTs(bx,pref[mbx],i).clear();
197  }
198  }
199  if (hasLCT) nbx++;
200  }
201 
202  if (infoV > 0) LogDebug("CSCMotherboardME11") <<"After x-bx sorting:";
203  nlct=0;
204  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++)
205  for (int i=0;i<CSCConstants::MAX_LCTS_PER_CSC;i++) {
206  if (allLCTs(bx,mbx,i).isValid()) {
207  nlct++;
208  if (infoV > 0) {
209  LogDebug("CSCMotherboardME11") << "LCT"<<i+1<<" "<<bx<<"/"
210  <<bx + mbx - match_trig_window_size/2<<": "<<allLCTs(bx,mbx,i);
211  }
212  }
213  }
214  if (infoV > 0 && nlct>0) LogDebug("CSCMotherboardME11") <<"bx "<<bx<<" nnLCT: "<<nlct;
215  } // x-bx sorting
216  }// end of for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++)
217 }
218 
219 
220 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::readoutLCTs1a() const
221 {
222  return readoutLCTs(ME1A);
223 }
224 
225 
226 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::readoutLCTs1b() const
227 {
228  return readoutLCTs(ME1B);
229 }
230 
231 
232 // Returns vector of read-out correlated LCTs, if any. Starts with
233 // the vector of all found LCTs and selects the ones in the read-out
234 // time window.
235 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::readoutLCTs(int me1ab) const
236 {
237  std::vector<CSCCorrelatedLCTDigi> tmpV;
238 
239  // The start time of the L1A*LCT coincidence window should be related
240  // to the fifo_pretrig parameter, but I am not completely sure how.
241  // Just choose it such that the window is centered at bx=7. This may
242  // need further tweaking if the value of tmb_l1a_window_size changes.
243  //static int early_tbins = 4;
244  // The number of LCT bins in the read-out is given by the
245  // tmb_l1a_window_size parameter, forced to be odd
246  const int lct_bins =
248  const int late_tbins = early_tbins + lct_bins;
249 
250 
251  // Start from the vector of all found correlated LCTs and select
252  // those within the LCT*L1A coincidence window.
253  int bx_readout = -1;
254  std::vector<CSCCorrelatedLCTDigi> all_lcts;
255  if (me1ab == ME1A) all_lcts = getLCTs1a();
256  if (me1ab == ME1B) all_lcts = getLCTs1b();
257  std::vector <CSCCorrelatedLCTDigi>::const_iterator plct = all_lcts.begin();
258  for (; plct != all_lcts.end(); plct++)
259  {
260  if (!plct->isValid()) continue;
261 
262  int bx = (*plct).getBX();
263  // Skip LCTs found too early relative to L1Accept.
264  if (bx <= early_tbins) continue;
265 
266  // Skip LCTs found too late relative to L1Accept.
267  if (bx > late_tbins) continue;
268 
269  // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window:
270  // in digi->raw step, LCTs have to be packed into the TMB header, and
271  // currently there is room just for two.
272  if (readout_earliest_2 && (bx_readout == -1 || bx == bx_readout) )
273  {
274  tmpV.push_back(*plct);
275  if (bx_readout == -1) bx_readout = bx;
276  }
277  else tmpV.push_back(*plct);
278  }
279  return tmpV;
280 }
281 
282 
283 // Returns vector of found correlated LCTs, if any.
284 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::getLCTs1b() const
285 {
286  std::vector<CSCCorrelatedLCTDigi> tmpV;
287 
288  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
289  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) {
290  for (int i=0;i<CSCConstants::MAX_LCTS_PER_CSC;i++) {
291  const CSCCorrelatedLCTDigi& lct = allLCTs.data[bx][mbx][i];
292  if (lct.isValid() and
294  tmpV.push_back(lct);
295  }
296  }
297  }
298  }
299  return tmpV;
300 }
301 
302 // Returns vector of found correlated LCTs, if any.
303 std::vector<CSCCorrelatedLCTDigi> CSCMotherboardME11::getLCTs1a() const
304 {
305  std::vector<CSCCorrelatedLCTDigi> tmpV;
306 
307  // disabled ME1a
308  if (mpc_block_me1a || disableME1a_) return tmpV;
309 
310  for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) {
311  for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) {
312  for (int i=0;i<CSCConstants::MAX_LCTS_PER_CSC;i++) {
313  const CSCCorrelatedLCTDigi& lct = allLCTs.data[bx][mbx][i];
314  if (lct.isValid() and
316  tmpV.push_back(lct);
317  }
318  }
319  }
320  } // Report all LCTs found.
321  return tmpV;
322 }
323 
324 
326 {
327  return cscTmbLUT_->doesALCTCrossCLCT(a, c, theEndcap, gangedME1a_);
328 }
329 
331  const CSCALCTDigi& sALCT,
332  const CSCCLCTDigi& bCLCT,
333  const CSCCLCTDigi& sCLCT,
334  CSCCorrelatedLCTDigi& lct1,
335  CSCCorrelatedLCTDigi& lct2) const
336 {
337  // assume that always anodeBestValid && cathodeBestValid
338  CSCALCTDigi bestALCT = bALCT;
339  CSCALCTDigi secondALCT = sALCT;
340  CSCCLCTDigi bestCLCT = bCLCT;
341  CSCCLCTDigi secondCLCT = sCLCT;
342 
343  if (ignoreAlctCrossClct) {
344  const bool anodeBestValid = bestALCT.isValid();
345  const bool anodeSecondValid = secondALCT.isValid();
346  const bool cathodeBestValid = bestCLCT.isValid();
347  const bool cathodeSecondValid = secondCLCT.isValid();
348  if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT;
349  if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT;
350  if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT;
351  if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT;
352  // ALCT-CLCT matching conditions are defined by "trig_enable" configuration
353  // parameters.
354  if ((alct_trig_enable and bestALCT.isValid()) or
355  (clct_trig_enable and bestCLCT.isValid()) or
356  (match_trig_enable and bestALCT.isValid() and bestCLCT.isValid())){
357  lct1 = constructLCTs(bestALCT, bestCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 1);
358  }
359  if (((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) and
360  ((alct_trig_enable and secondALCT.isValid()) or
361  (clct_trig_enable and secondCLCT.isValid()) or
362  (match_trig_enable and secondALCT.isValid() and secondCLCT.isValid()))){
363  lct2 = constructLCTs(secondALCT, secondCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 2);
364  }
365  return;
366  }
367  else {
368 
369  if (secondALCT == bestALCT) secondALCT.clear();
370  if (secondCLCT == bestCLCT) secondCLCT.clear();
371 
372  const int ok11 = doesALCTCrossCLCT( bestALCT, bestCLCT);
373  const int ok12 = doesALCTCrossCLCT( bestALCT, secondCLCT);
374  const int ok21 = doesALCTCrossCLCT( secondALCT, bestCLCT);
375  const int ok22 = doesALCTCrossCLCT( secondALCT, secondCLCT);
376  const int code = (ok11<<3) | (ok12<<2) | (ok21<<1) | (ok22);
377 
378  int dbg=0;
379  if (dbg) LogTrace("CSCMotherboardME11")<<"debug correlateLCTs in ME11 "<< cscId_ <<std::endl
380  <<"ALCT1: "<<bestALCT<<std::endl
381  <<"ALCT2: "<<secondALCT<<std::endl
382  <<"CLCT1: "<<bestCLCT<<std::endl
383  <<"CLCT2: "<<secondCLCT<<std::endl
384  <<"ok 11 12 21 22 code = "<<ok11<<" "<<ok12<<" "<<ok21<<" "<<ok22<<" "<<code<<std::endl;
385 
386  if ( code==0 ) return;
387 
388  // LUT defines correspondence between possible ok## combinations
389  // and resulting lct1 and lct2
390  int lut[16][2] = {
391  //ok: 11 12 21 22
392  {0 ,0 }, // 0 0 0 0
393  {22,0 }, // 0 0 0 1
394  {21,0 }, // 0 0 1 0
395  {21,22}, // 0 0 1 1
396  {12,0 }, // 0 1 0 0
397  {12,22}, // 0 1 0 1
398  {12,21}, // 0 1 1 0
399  {12,21}, // 0 1 1 1
400  {11,0 }, // 1 0 0 0
401  {11,22}, // 1 0 0 1
402  {11,21}, // 1 0 1 0
403  {11,22}, // 1 0 1 1
404  {11,12}, // 1 1 0 0
405  {11,22}, // 1 1 0 1
406  {11,12}, // 1 1 1 0
407  {11,22}, // 1 1 1 1
408  };
409 
410  if (dbg) LogTrace("CSCMotherboardME11")<<"lut 0 1 = "<<lut[code][0]<<" "<<lut[code][1]<<std::endl;
411 
412  switch (lut[code][0]) {
413  case 11:
414  lct1 = constructLCTs(bestALCT, bestCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 1);
415  break;
416  case 12:
417  lct1 = constructLCTs(bestALCT, secondCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 1);
418  break;
419  case 21:
420  lct1 = constructLCTs(secondALCT, bestCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 1);
421  break;
422  case 22:
423  lct1 = constructLCTs(secondALCT, secondCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 1);
424  break;
425  default: return;
426  }
427 
428  if (dbg) LogTrace("CSCMotherboardME11")<<"lct1: "<<lct1<<std::endl;
429 
430  switch (lut[code][1]){
431  case 12:
432  lct2 = constructLCTs(bestALCT, secondCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 2);
433  if (dbg) LogTrace("CSCMotherboardME11")<<"lct2: "<<lct2<<std::endl;
434  return;
435  case 21:
436  lct2 = constructLCTs(secondALCT, bestCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 2);
437  if (dbg) LogTrace("CSCMotherboardME11")<<"lct2: "<<lct2<<std::endl;
438  return;
439  case 22:
440  lct2 = constructLCTs(secondALCT, secondCLCT, CSCCorrelatedLCTDigi::ALCTCLCT, 2);
441  if (dbg) LogTrace("CSCMotherboardME11")<<"lct2: "<<lct2<<std::endl;
442  return;
443  default: return;
444  }
445  if (dbg) LogTrace("CSCMotherboardME11")<<"out of correlateLCTsME11"<<std::endl;
446 
447  return;
448  }
449 }
450 
451 
#define LogDebug(id)
CSCCorrelatedLCTDigi data[CSCConstants::MAX_LCT_TBINS][CSCConstants::MAX_MATCH_WINDOW_SIZE][CSCConstants::MAX_LCTS_PER_CSC]
int getStrip() const
return the key halfstrip from 0,159
T getParameter(std::string const &) const
std::vector< CSCCLCTDigi > clctV
unsigned int clct_trig_enable
void setConfigParameters(const CSCDBL1TPParameters *conf)
const unsigned theEndcap
Definition: CSCBaseboard.h:33
unsigned int match_trig_window_size
std::vector< CSCCorrelatedLCTDigi > getLCTs1a() const
bool isValid() const
check ALCT validity (1 - valid ALCT)
Definition: CSCALCTDigi.h:30
void clear()
clear this ALCT
Definition: CSCALCTDigi.cc:35
std::unique_ptr< CSCCathodeLCTProcessor > clctProc
bool disableME1a_
Definition: CSCBaseboard.h:77
int pref[CSCConstants::MAX_LCT_TBINS]
CSCDetId cscId_
Definition: CSCBaseboard.h:46
bool gangedME1a_
Definition: CSCBaseboard.h:77
void run(const CSCWireDigiCollection *wiredc, const CSCComparatorDigiCollection *compdc) override
unsigned int mpc_block_me1a
void correlateLCTsME11(const CSCALCTDigi &bestALCT, const CSCALCTDigi &secondALCT, const CSCCLCTDigi &bestCLCT, const CSCCLCTDigi &secondCLCT, CSCCorrelatedLCTDigi &lct1, CSCCorrelatedLCTDigi &lct2) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
std::vector< CSCALCTDigi > alctV
~CSCMotherboardME11() override
unsigned int tmb_l1a_window_size
bool isValid() const
check CLCT validity (1 - valid CLCT)
Definition: CSCCLCTDigi.h:30
std::unique_ptr< CSCMotherboardLUTME11 > cscTmbLUT_
unsigned int match_trig_enable
CSCCorrelatedLCTDigi constructLCTs(const CSCALCTDigi &aLCT, const CSCCLCTDigi &cLCT, int type, int trknmb) const
std::vector< CSCCorrelatedLCTDigi > readoutLCTs1a() const
#define LogTrace(id)
std::vector< CSCCorrelatedLCTDigi > readoutLCTs1b() const
bool doesALCTCrossCLCT(const CSCALCTDigi &a, const CSCCLCTDigi &c) const
const CSCGeometry * cscGeometry_
Definition: CSCBaseboard.h:54
edm::ParameterSet tmbParams_
Definition: CSCBaseboard.h:61
std::vector< CSCCorrelatedLCTDigi > getLCTs1b() const
double b
Definition: hdecay.h:120
unsigned int alct_trig_enable
bool isValid() const
return valid pattern bit
std::vector< CSCCorrelatedLCTDigi > readoutLCTs() const override
std::unique_ptr< CSCAnodeLCTProcessor > alctProc
double a
Definition: hdecay.h:121
void clear()
clear this CLCT
Definition: CSCCLCTDigi.cc:58
unsigned int alctClctOffset_
Definition: CSCBaseboard.h:86