CMS 3D CMS Logo

CSCTMBHeader.cc
Go to the documentation of this file.
11 #include <cmath>
12 #include <cstring> // memcpy
13 
14 #ifdef LOCAL_UNPACK
15 bool CSCTMBHeader::debug = false;
16 #else
17 std::atomic<bool> CSCTMBHeader::debug{false};
18 #endif
19 
20 CSCTMBHeader::CSCTMBHeader(int firmwareVersion, int firmwareRevision):
21  theHeaderFormat(),
22  theFirmwareVersion(firmwareVersion)
23 {
24  if(firmwareVersion == 2013)
25  {
26  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2013());
27  }
28  else if(firmwareVersion == 2006)
29  {
30  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2006());
31  }
32  else if(firmwareVersion == 2007)
33  {
34 
35  /* Checks for TMB2007 firmware revisions ranges to detect data format
36  * rev.0x50c3 - first revision with changed format
37  * rev.0x42D5 - oldest known from 06/21/2007
38  * There is 4-bits year value rollover in revision number (0 in 2016)
39  */
40  if((firmwareRevision >= 0x50c3) || (firmwareRevision < 0x42D5))
41  {
42  // if (firmwareRevision >= 0x7a76) // First OTMB firmware revision with 2013 format
43  /* Revisions > 0x6000 - OTMB firmwares, < 0x42D5 - new TMB revisions in 2016 */
44  if ((firmwareRevision >= 0x6000) || (firmwareRevision < 0x42D5))
45  {
46  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2013());
47  }
48  else
49  {
50  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007_rev0x50c3());
51  }
52  }
53  else
54  {
55  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007());
56  }
57  }
58  else
59  {
60  edm::LogError("CSCTMBHeader|CSCRawToDigi") <<"failed to determine TMB firmware version!!";
61  }
62 }
63 
64 //CSCTMBHeader::CSCTMBHeader(const CSCTMBStatusDigi & digi) {
65 // CSCTMBHeader(digi.header());
66 //}
67 
68 CSCTMBHeader::CSCTMBHeader(const unsigned short * buf)
69  : theHeaderFormat()
70 {
72  if (buf[0]==0xDB0C)
73  {
74  theFirmwareVersion=2007;
75  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007(buf));
76  /* Checks for TMB2007 firmware revisions ranges to detect data format
77  * rev.0x50c3 - first revision with changed format
78  * rev.0x42D5 - oldest known from 06/21/2007
79  * There is 4-bits year value rollover in revision number (0 in 2016)
80  */
81  if ((theHeaderFormat->firmwareRevision() >= 0x50c3) || (theHeaderFormat->firmwareRevision() < 0x42D5))
82  {
83  // if (theHeaderFormat->firmwareRevision() >= 0x7a76) // First OTMB firmware revision with 2013 format
84  /* Revisions > 0x6000 - OTMB firmwares, < 0x42D5 - new TMB revisions in 2016 */
85  if ((theHeaderFormat->firmwareRevision() >= 0x6000) || (theHeaderFormat->firmwareRevision() < 0x42D5))
86  {
87  theFirmwareVersion=2013;
88  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2013(buf));
89  }
90  else
91  {
92  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2007_rev0x50c3(buf));
93  }
94  }
95 
96  }
97  else if (buf[0]==0x6B0C)
98  {
99  theFirmwareVersion=2006;
100  theHeaderFormat = boost::shared_ptr<CSCVTMBHeaderFormat>(new CSCTMBHeader2006(buf));
101  }
102  else
103  {
104  edm::LogError("CSCTMBHeader|CSCRawToDigi") <<"failed to determine TMB firmware version!!";
105  }
106 }
107 
108 /*
109 void CSCTMBHeader::swapCLCTs(CSCCLCTDigi& digi1, CSCCLCTDigi& digi2)
110 {
111  bool me11 = (theChamberId.station() == 1 &&
112  (theChamberId.ring() == 1 || theChamberId.ring() == 4));
113  if (!me11) return;
114 
115  int cfeb1 = digi1.getCFEB();
116  int cfeb2 = digi2.getCFEB();
117  if (cfeb1 != cfeb2) return;
118 
119  bool me1a = (cfeb1 == 4);
120  bool me1b = (cfeb1 != 4);
121  bool zplus = (theChamberId.endcap() == 1);
122 
123  if ( (me1a && zplus) || (me1b && !zplus)) {
124  // Swap CLCTs if they have the same quality and pattern # (priority
125  // has to be given to the lower key).
126  if (digi1.getQuality() == digi2.getQuality() &&
127  digi1.getPattern() == digi2.getPattern()) {
128  CSCCLCTDigi temp = digi1;
129  digi1 = digi2;
130  digi2 = temp;
131 
132  // Also re-number them.
133  digi1.setTrknmb(1);
134  digi2.setTrknmb(2);
135  }
136  }
137 }
138 */
139 
140 
141 //FIXME Pick which LCT goes first
142 void CSCTMBHeader::add(const std::vector<CSCCLCTDigi> & digis)
143 {
144  // sort???
145  if(!digis.empty()) {
146  addCLCT0(digis[0]);
147 
148  }
149  if(digis.size() > 1) addCLCT1(digis[1]);
150 }
151 
152 void CSCTMBHeader::add(const std::vector<CSCCorrelatedLCTDigi> & digis)
153 {
154  // sort???
155  if(!digis.empty()) addCorrelatedLCT0(digis[0]);
156  if(digis.size() > 1) addCorrelatedLCT1(digis[1]);
157 }
158 
159 
161 {
162  CSCTMBHeader2007 * result = dynamic_cast<CSCTMBHeader2007 *>(theHeaderFormat.get());
163  if(result == nullptr)
164  {
165  throw cms::Exception("Could not get 2007 TMB header format");
166  }
167  return *result;
168 }
169 
171 {
173  if(result == nullptr)
174  {
175  throw cms::Exception("Could not get 2007 rev0x50c3 TMB header format");
176  }
177  return *result;
178 }
179 
181 {
182  CSCTMBHeader2013 * result = dynamic_cast<CSCTMBHeader2013 *>(theHeaderFormat.get());
183  if(result == nullptr)
184  {
185  throw cms::Exception("Could not get 2013 TMB header format");
186  }
187  return *result;
188 }
189 
190 
192 {
193  CSCTMBHeader2006 * result = dynamic_cast<CSCTMBHeader2006 *>(theHeaderFormat.get());
194  if(result == nullptr)
195  {
196  throw cms::Exception("Could not get 2006 TMB header format");
197  }
198  return *result;
199 }
200 
201 
203 {
204  constexpr bool debug = false;
205 
206  // tests packing and unpacking
207  for(int station = 1; station <= 4; ++station)
208  {
209  for(int iendcap = 1; iendcap <= 2; ++iendcap)
210  {
211  CSCDetId detId(iendcap, station, 1, 1, 0);
212 
213  // the next-to-last is the BX, which only gets
214  // saved in two bits and must be the same for clct0 and clct1.
215  //CSCCLCTDigi clct0(1, 1, 4, 0, 0, 30, 3, 0, 1); // valid for 2006
216  // In 2007 firmware, there are no distrips, so the 4th argument (strip
217  // type) should always be set to 1 (halfstrips).
218  CSCCLCTDigi clct0(1, 1, 4, 1, 0, 30, 4, 2, 1); // valid for 2007
219  CSCCLCTDigi clct1(1, 1, 2, 1, 1, 31, 1, 2, 2);
220 
221  // BX of LCT (8th argument) is 1-bit word (the least-significant bit
222  // of ALCT's bx).
223  CSCCorrelatedLCTDigi lct0(1, 1, 2, 10, 98, 5, 0, 1, 0, 0, 0, 0);
224  CSCCorrelatedLCTDigi lct1(2, 1, 2, 20, 15, 9, 1, 0, 0, 0, 0, 0);
225 
226  CSCTMBHeader tmbHeader(2007, 0x50c3);
227  tmbHeader.addCLCT0(clct0);
228  tmbHeader.addCLCT1(clct1);
229  tmbHeader.addCorrelatedLCT0(lct0);
230  tmbHeader.addCorrelatedLCT1(lct1);
231  std::vector<CSCCLCTDigi> clcts = tmbHeader.CLCTDigis(detId.rawId());
232  // guess they got reordered
233  assert(cscPackerCompare(clcts[0],clct0));
234  assert(cscPackerCompare(clcts[1],clct1));
235  if (debug)
236  {
237  std::cout << "Match for: " << clct0 << "\n";
238  std::cout << " " << clct1 << "\n \n";
239  }
240 
241  std::vector<CSCCorrelatedLCTDigi> lcts = tmbHeader.CorrelatedLCTDigis(detId.rawId());
242  assert(cscPackerCompare(lcts[0], lct0));
243  assert(cscPackerCompare(lcts[1], lct1));
244  if (debug)
245  {
246  std::cout << "Match for: " << lct0 << "\n";
247  std::cout << " " << lct1 << "\n";
248  }
249 
250  // try packing and re-packing, to make sure they're the same
251  unsigned short int * data = tmbHeader.data();
252  CSCTMBHeader newHeader(data);
253  clcts = newHeader.CLCTDigis(detId.rawId());
254  assert(cscPackerCompare(clcts[0],clct0));
255  assert(cscPackerCompare(clcts[1],clct1));
256  lcts = newHeader.CorrelatedLCTDigis(detId.rawId());
257  assert(cscPackerCompare(lcts[0], lct0));
258  assert(cscPackerCompare(lcts[1], lct1));
259 
260 
261  }
262  }
263 }
264 
265 
266 std::ostream & operator<<(std::ostream & os, const CSCTMBHeader & hdr)
267 {
268  hdr.theHeaderFormat->print(os);
269  return os;
270 }
CSCTMBHeader2007 tmbHeader2007() const
will throw if the cast fails
int theFirmwareVersion
Definition: CSCTMBHeader.h:164
std::vector< CSCCorrelatedLCTDigi > CorrelatedLCTDigis(uint32_t idlayer) const
returns CorrelatedLCT digis
Definition: CSCTMBHeader.h:104
void addCorrelatedLCT0(const CSCCorrelatedLCTDigi &digi)
Definition: CSCTMBHeader.h:136
void add(const std::vector< CSCCLCTDigi > &digis)
these methods need more brains to figure which one goes first
void addCorrelatedLCT1(const CSCCorrelatedLCTDigi &digi)
Definition: CSCTMBHeader.h:139
#define constexpr
void addCLCT1(const CSCCLCTDigi &digi)
Definition: CSCTMBHeader.h:133
uint32_t rawId() const
get the raw id
Definition: DetId.h:44
boost::shared_ptr< CSCVTMBHeaderFormat > theHeaderFormat
Definition: CSCTMBHeader.h:163
static void selfTest()
tests that packing and unpacking give same results
unsigned short * data()
Definition: CSCTMBHeader.h:117
static std::atomic< bool > debug
Definition: CSCTMBHeader.h:160
friend std::ostream & operator<<(std::ostream &os, const CSCTMBHeader &hdr)
std::vector< CSCCLCTDigi > CLCTDigis(uint32_t idlayer)
returns CLCT digis
Definition: CSCTMBHeader.h:98
CSCTMBHeader2006 tmbHeader2006() const
CSCTMBHeader2007_rev0x50c3 tmbHeader2007_rev0x50c3() const
void addCLCT0(const CSCCLCTDigi &digi)
Needed before data packing.
Definition: CSCTMBHeader.h:132
bool cscPackerCompare(const T &t1, const T &t2)
CSCTMBHeader(int firmwareVersion, int firmwareRevision)
Definition: CSCTMBHeader.cc:20
CSCTMBHeader2013 tmbHeader2013() const