CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CSCTMBHeader.cc
Go to the documentation of this file.
15 #include <cmath>
16 #include <cstring> // memcpy
17 
18 #ifdef LOCAL_UNPACK
19 bool CSCTMBHeader::debug = false;
20 #else
21 std::atomic<bool> CSCTMBHeader::debug{false};
22 #endif
23 
24 CSCTMBHeader::CSCTMBHeader(int firmwareVersion, int firmwareRevision)
25  : theHeaderFormat(), theFirmwareVersion(firmwareVersion) {
26  if (firmwareVersion == 2020) {
27  if ((firmwareRevision < 0x4000) && (firmwareRevision > 0x0)) { /* New (O)TMB firmware revision format */
28  bool isGEM_fw = false;
29  bool isCCLUT_HMT_fw = false;
30  bool isOTMB_Run2_fw = false;
31  bool isTMB_Run3_fw = false;
32  bool isTMB_Run2_fw = false;
33  bool isRun2_df = false;
34  unsigned df_version = (firmwareRevision >> 9) & 0xF; // 4-bits Data Format version
35  unsigned major_ver = (firmwareRevision >> 5) & 0xF; // 4-bits major version part
36  // unsigned minor_ver = firmwareRevision & 0x1F; // 5-bits minor version part
37  switch (df_version) {
38  case 0x3:
39  isGEM_fw = true;
40  break;
41  case 0x2:
42  isCCLUT_HMT_fw = true;
43  break;
44  case 0x1:
45  isOTMB_Run2_fw = true;
46  break;
47  case 0x0:
48  if (major_ver == 1)
49  isTMB_Run2_fw = true;
50  else
51  isTMB_Run3_fw = true;
52  break;
53  default:
54  isGEM_fw = true;
55  }
56  if (major_ver == 1) {
57  isRun2_df = true;
58  }
59 
60  if (isGEM_fw) {
61  if (isRun2_df) {
62  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_Run2(firmwareRevision));
63  } else {
64  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_GEM());
65  }
66  } else if (isCCLUT_HMT_fw) {
67  if (isRun2_df) {
68  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_Run2(firmwareRevision));
69  } else {
70  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_CCLUT());
71  }
72  } else if (isOTMB_Run2_fw || isTMB_Run2_fw || isRun2_df) {
73  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_Run2(firmwareRevision));
74  } else if (isTMB_Run3_fw) {
75  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_TMB());
76  }
77  }
78  } else if (firmwareVersion == 2013) {
79  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2013());
80  } else if (firmwareVersion == 2006) {
81  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2006());
82  } else if (firmwareVersion == 2007) {
83  /* Checks for TMB2007 firmware revisions ranges to detect data format
84  * rev.0x50c3 - first revision with changed format
85  * rev.0x42D5 - oldest known from 06/21/2007
86  * There is 4-bits year value rollover in revision number (0 in 2016)
87  */
88  if ((firmwareRevision >= 0x50c3) || (firmwareRevision < 0x42D5)) {
89  // if (firmwareRevision >= 0x7a76) // First OTMB firmware revision with 2013 format
90  /* Revisions > 0x6000 - OTMB firmwares, < 0x42D5 - new TMB revisions in 2016 */
91  if ((firmwareRevision >= 0x6000) || (firmwareRevision < 0x42D5)) {
92  bool isGEMfirmware = false;
93  /* There are OTMB2013 firmware versions exist, which reports firmwareRevision code = 0x0 */
94  if ((firmwareRevision < 0x4000) && (firmwareRevision > 0x0)) { /* New (O)TMB firmware revision format */
95  if (((firmwareRevision >> 9) & 0x3) == 0x3)
96  isGEMfirmware = true;
97  if (isGEMfirmware) {
98  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_GEM());
99  } else {
100  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2013());
101  }
102  }
103  } else {
104  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007_rev0x50c3());
105  }
106  } else {
107  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007());
108  }
109  } else {
110  edm::LogError("CSCTMBHeader|CSCRawToDigi") << "failed to determine TMB firmware version!!";
111  }
112 }
113 
114 //CSCTMBHeader::CSCTMBHeader(const CSCTMBStatusDigi & digi) {
115 // CSCTMBHeader(digi.header());
116 //}
117 
118 CSCTMBHeader::CSCTMBHeader(const unsigned short *buf) : theHeaderFormat() {
120  if (buf[0] == 0xDB0C) {
121  theFirmwareVersion = 2007;
122  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007(buf));
123  /* Checks for TMB2007 firmware revisions ranges to detect data format
124  * rev.0x50c3 - first revision with changed format
125  * rev.0x42D5 - oldest known from 06/21/2007
126  * There is 4-bits year value rollover in revision number (0 in 2016)
127  */
128  if ((theHeaderFormat->firmwareRevision() >= 0x50c3) || (theHeaderFormat->firmwareRevision() < 0x42D5)) {
129  // if (theHeaderFormat->firmwareRevision() >= 0x7a76) // First OTMB firmware revision with 2013 format
130  /* Revisions > 0x6000 - OTMB firmwares, < 0x42D5 - new TMB revisions in 2016 */
131  if ((theHeaderFormat->firmwareRevision() >= 0x6000) || (theHeaderFormat->firmwareRevision() < 0x42D5)) {
132  theFirmwareVersion = 2013;
133  bool isGEM_fw = false;
134  bool isCCLUT_HMT_fw = false;
135  bool isOTMB_Run2_fw = false;
136  bool isTMB_Run3_fw = false;
137  bool isTMB_Run2_fw = false;
138  bool isRun2_df = false;
139  unsigned firmwareRevision = theHeaderFormat->firmwareRevision();
140  /* There are OTMB2013 firmware versions exist, which reports firmwareRevision code = 0x0 */
141  if ((firmwareRevision < 0x4000) && (firmwareRevision > 0x0)) { /* New (O)TMB firmware revision format */
142  theFirmwareVersion = 2020;
143  unsigned df_version = (firmwareRevision >> 9) & 0xF; // 4-bits Data Format version
144  unsigned major_ver = (firmwareRevision >> 5) & 0xF; // 4-bits major version part
145  // unsigned minor_ver = firmwareRevision & 0x1F; // 5-bits minor version part
146  switch (df_version) {
147  case 0x3:
148  isGEM_fw = true;
149  break;
150  case 0x2:
151  isCCLUT_HMT_fw = true;
152  break;
153  case 0x1:
154  isOTMB_Run2_fw = true;
155  break;
156  case 0x0:
157  if (major_ver == 1)
158  isTMB_Run2_fw = true;
159  else
160  isTMB_Run3_fw = true;
161  break;
162  default:
163  isGEM_fw = true;
164  }
165  if (major_ver == 1) {
166  isRun2_df = true;
167  }
168  }
169  if (theFirmwareVersion == 2020) {
170  if (isGEM_fw) {
171  if (isRun2_df) {
172  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_Run2(buf));
173  } else {
174  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_GEM(buf));
175  }
176  } else if (isCCLUT_HMT_fw) {
177  if (isRun2_df) {
178  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_Run2(buf));
179  } else {
180  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_CCLUT(buf));
181  }
182  } else if (isOTMB_Run2_fw || isTMB_Run2_fw || isRun2_df) {
183  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_Run2(buf));
184  } else if (isTMB_Run3_fw) {
185  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2020_TMB(buf));
186  }
187 
188  } else {
189  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2013(buf));
190  }
191 
192  } else {
193  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007_rev0x50c3(buf));
194  }
195  }
196 
197  } else if (buf[0] == 0x6B0C) {
198  theFirmwareVersion = 2006;
199  theHeaderFormat = std::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2006(buf));
200  } else {
201  edm::LogError("CSCTMBHeader|CSCRawToDigi") << "failed to determine TMB firmware version!!";
202  }
203 }
204 
205 /*
206 void CSCTMBHeader::swapCLCTs(CSCCLCTDigi& digi1, CSCCLCTDigi& digi2)
207 {
208  bool me11 = (theChamberId.station() == 1 &&
209  (theChamberId.ring() == 1 || theChamberId.ring() == 4));
210  if (!me11) return;
211 
212  int cfeb1 = digi1.getCFEB();
213  int cfeb2 = digi2.getCFEB();
214  if (cfeb1 != cfeb2) return;
215 
216  bool me1a = (cfeb1 == 4);
217  bool me1b = (cfeb1 != 4);
218  bool zplus = (theChamberId.endcap() == 1);
219 
220  if ( (me1a && zplus) || (me1b && !zplus)) {
221  // Swap CLCTs if they have the same quality and pattern # (priority
222  // has to be given to the lower key).
223  if (digi1.getQuality() == digi2.getQuality() &&
224  digi1.getPattern() == digi2.getPattern()) {
225  CSCCLCTDigi temp = digi1;
226  digi1 = digi2;
227  digi2 = temp;
228 
229  // Also re-number them.
230  digi1.setTrknmb(1);
231  digi2.setTrknmb(2);
232  }
233  }
234 }
235 */
236 
237 //FIXME Pick which LCT goes first
238 void CSCTMBHeader::add(const std::vector<CSCCLCTDigi> &digis) {
239  // sort???
240  if (!digis.empty()) {
241  addCLCT0(digis[0]);
242  }
243  if (digis.size() > 1)
244  addCLCT1(digis[1]);
245 }
246 
247 void CSCTMBHeader::add(const std::vector<CSCCorrelatedLCTDigi> &digis) {
248  // sort???
249  if (!digis.empty())
250  addCorrelatedLCT0(digis[0]);
251  if (digis.size() > 1)
252  addCorrelatedLCT1(digis[1]);
253 }
254 
255 void CSCTMBHeader::add(const std::vector<CSCShowerDigi> &digis) {
256  if (!digis.empty())
257  theHeaderFormat->addShower(digis[0]);
258 }
259 
261  CSCTMBHeader2007 *result = dynamic_cast<CSCTMBHeader2007 *>(theHeaderFormat.get());
262  if (result == nullptr) {
263  throw cms::Exception("Could not get 2007 TMB header format");
264  }
265  return *result;
266 }
267 
270  if (result == nullptr) {
271  throw cms::Exception("Could not get 2007 rev0x50c3 TMB header format");
272  }
273  return *result;
274 }
275 
277  CSCTMBHeader2013 *result = dynamic_cast<CSCTMBHeader2013 *>(theHeaderFormat.get());
278  if (result == nullptr) {
279  throw cms::Exception("Could not get 2013 TMB header format");
280  }
281  return *result;
282 }
283 
286  if (result == nullptr) {
287  throw cms::Exception("Could not get 2020 TMB Run3 header format");
288  }
289  return *result;
290 }
291 
294  if (result == nullptr) {
295  throw cms::Exception("Could not get 2020 (O)TMB CCLUT header format");
296  }
297  return *result;
298 }
299 
302  if (result == nullptr) {
303  throw cms::Exception("Could not get 2020 (O)TMB GEM header format");
304  }
305  return *result;
306 }
307 
310  if (result == nullptr) {
311  throw cms::Exception("Could not get 2020 (O)TMB legacy Run2 header format");
312  }
313  return *result;
314 }
315 
317  CSCTMBHeader2006 *result = dynamic_cast<CSCTMBHeader2006 *>(theHeaderFormat.get());
318  if (result == nullptr) {
319  throw cms::Exception("Could not get 2006 TMB header format");
320  }
321  return *result;
322 }
323 
324 void CSCTMBHeader::selfTest(int firmwareVersion, int firmwareRevision) {
325  constexpr bool debug = false;
326 
327  // tests packing and unpacking
328  for (int station = 1; station <= 4; ++station) {
329  for (int iendcap = 1; iendcap <= 2; ++iendcap) {
330  CSCDetId detId(iendcap, station, 1, 1, 0);
331 
332  // the next-to-last is the BX, which only gets
333  // saved in two bits and must be the same for clct0 and clct1.
334  //CSCCLCTDigi clct0(1, 1, 4, 0, 0, 30, 3, 0, 1); // valid for 2006
335  // In 2007 firmware, there are no distrips, so the 4th argument (strip
336  // type) should always be set to 1 (halfstrips).
337  CSCCLCTDigi clct0(1, 1, 4, 1, 0, 30, 4, 2, 1); // valid for 2007
338  CSCCLCTDigi clct1(1, 1, 3, 1, 1, 31, 1, 2, 2);
339 
340  // BX of LCT (8th argument) is 1-bit word (the least-significant bit
341  // of ALCT's bx).
342  CSCCorrelatedLCTDigi lct0(1, 1, 2, 10, 98, 5, 0, 1, 0, 0, 0, 0);
343  CSCCorrelatedLCTDigi lct1(2, 1, 2, 20, 15, 9, 1, 0, 0, 0, 0, 0);
344 
345  // Use Run3 format digis for TMB firmwareVersion 2020
346  // and revision codes for MEx1 CCLUT, ME11 CCLUT/GEM
347  if (firmwareVersion >= 2020) {
348  bool isGEM_fw = false;
349  bool isCCLUT_HMT_fw = false;
350  bool isOTMB_Run2_fw = false;
351  bool isTMB_Run3_fw = false;
352  bool isTMB_Run2_fw = false;
353  bool isRun2_df = false;
354  unsigned df_version = (firmwareRevision >> 9) & 0xF; // 4-bits Data Format version
355  unsigned major_ver = (firmwareRevision >> 5) & 0xF; // 4-bits major version part
356  // unsigned minor_ver = firmwareRevision & 0x1F; // 5-bits minor version part
357  switch (df_version) {
358  case 0x3:
359  isGEM_fw = true;
360  break;
361  case 0x2:
362  isCCLUT_HMT_fw = true;
363  break;
364  case 0x1:
365  isOTMB_Run2_fw = true;
366  break;
367  case 0x0:
368  if (major_ver == 1)
369  isTMB_Run2_fw = true;
370  else
371  isTMB_Run3_fw = true;
372  break;
373  default:
374  isGEM_fw = true;
375  }
376  if (major_ver == 1) {
377  isRun2_df = true;
378  }
379  if ((isGEM_fw || isCCLUT_HMT_fw) && !isRun2_df && !isOTMB_Run2_fw && !isTMB_Run2_fw) {
380  clct0 = CSCCLCTDigi(
381  1, 6, 6, 1, 0, (120 % 32), (120 / 32), 2, 1, 3, 0xebf, CSCCLCTDigi::Version::Run3, true, false, 2, 6);
382  clct1 = CSCCLCTDigi(
383  1, 6, 3, 1, 1, (132 % 32), (132 / 32), 2, 2, 3, 0xe54, CSCCLCTDigi::Version::Run3, false, true, 1, 15);
384  }
385  if ((isGEM_fw || isCCLUT_HMT_fw || isTMB_Run3_fw) && !isRun2_df && !isOTMB_Run2_fw && !isTMB_Run2_fw) {
386  lct0 = CSCCorrelatedLCTDigi(
387  1, 1, 3, 85, 120, 6, 0, 0, 0, 0, 0, 0, CSCCorrelatedLCTDigi::Version::Run3, true, false, 2, 6);
388  lct1 = CSCCorrelatedLCTDigi(
389  2, 1, 2, 81, 132, 3, 1, 0, 0, 0, 0, 0, CSCCorrelatedLCTDigi::Version::Run3, false, true, 0, 15);
390  }
391  }
392 
393  CSCTMBHeader tmbHeader(firmwareVersion, firmwareRevision);
394  tmbHeader.addCLCT0(clct0);
395  tmbHeader.addCLCT1(clct1);
396  tmbHeader.addCorrelatedLCT0(lct0);
397  tmbHeader.addCorrelatedLCT1(lct1);
398  std::vector<CSCCLCTDigi> clcts = tmbHeader.CLCTDigis(detId.rawId());
399  // guess they got reordered
400  assert(cscPackerCompare(clcts[0], clct0));
401  assert(cscPackerCompare(clcts[1], clct1));
402  if (debug) {
403  std::cout << "Match for: " << clct0 << "\n";
404  std::cout << " " << clct1 << "\n \n";
405  }
406 
407  std::vector<CSCCorrelatedLCTDigi> lcts = tmbHeader.CorrelatedLCTDigis(detId.rawId());
408  assert(cscPackerCompare(lcts[0], lct0));
409  assert(cscPackerCompare(lcts[1], lct1));
410  if (debug) {
411  std::cout << "Match for: " << lct0 << "\n";
412  std::cout << " " << lct1 << "\n";
413  }
414 
415  // try packing and re-packing, to make sure they're the same
416  unsigned short int *data = tmbHeader.data();
417  CSCTMBHeader newHeader(data);
418  clcts = newHeader.CLCTDigis(detId.rawId());
419  assert(cscPackerCompare(clcts[0], clct0));
420  assert(cscPackerCompare(clcts[1], clct1));
421  lcts = newHeader.CorrelatedLCTDigis(detId.rawId());
422  assert(cscPackerCompare(lcts[0], lct0));
423  assert(cscPackerCompare(lcts[1], lct1));
424  }
425  }
426 }
427 
428 std::ostream &operator<<(std::ostream &os, const CSCTMBHeader &hdr) {
429  hdr.theHeaderFormat->print(os);
430  return os;
431 }
CSCTMBHeader2007 tmbHeader2007() const
will throw if the cast fails
int theFirmwareVersion
Definition: CSCTMBHeader.h:144
std::vector< CSCCorrelatedLCTDigi > CorrelatedLCTDigis(uint32_t idlayer) const
returns CorrelatedLCT digis
Definition: CSCTMBHeader.h:97
std::shared_ptr< CSCVTMBHeaderFormat > theHeaderFormat
Definition: CSCTMBHeader.h:143
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
void addCorrelatedLCT0(const CSCCorrelatedLCTDigi &digi)
Definition: CSCTMBHeader.h:119
void add(const std::vector< CSCCLCTDigi > &digis)
these methods need more brains to figure which one goes first
Log< level::Error, false > LogError
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:167
assert(be >=bs)
CSCTMBHeader2020_CCLUT tmbHeader2020_CCLUT() const
void addCorrelatedLCT1(const CSCCorrelatedLCTDigi &digi)
Definition: CSCTMBHeader.h:120
tuple result
Definition: mps_fire.py:311
void addCLCT1(const CSCCLCTDigi &digi)
Definition: CSCTMBHeader.h:116
CSCTMBHeader2020_TMB tmbHeader2020_TMB() const
unsigned short * data()
Definition: CSCTMBHeader.h:107
static std::atomic< bool > debug
Definition: CSCTMBHeader.h:140
std::vector< CSCCLCTDigi > CLCTDigis(uint32_t idlayer)
returns CLCT digis
Definition: CSCTMBHeader.h:94
CSCTMBHeader2006 tmbHeader2006() const
CSCTMBHeader2007_rev0x50c3 tmbHeader2007_rev0x50c3() const
void addCLCT0(const CSCCLCTDigi &digi)
for data packing
Definition: CSCTMBHeader.h:115
bool cscPackerCompare(const T &t1, const T &t2)
static void selfTest(int firmwwareVersion, int firmwareRevision)
tests that packing and unpacking give same results
CSCTMBHeader2020_Run2 tmbHeader2020_Run2() const
CSCTMBHeader2020_GEM tmbHeader2020_GEM() const
tuple cout
Definition: gather_cfg.py:144
CSCTMBHeader(int firmwareVersion, int firmwareRevision)
Definition: CSCTMBHeader.cc:24
CSCTMBHeader2013 tmbHeader2013() const