CMS 3D CMS Logo

CSCCFEBData.cc
Go to the documentation of this file.
1 
9 #include <cassert>
10 
11 CSCCFEBData::CSCCFEBData(unsigned number, const uint16_t *buf, uint16_t format_version, bool f_dcfeb)
12  : theSize(0), boardNumber_(number), theNumberOfSamples(0), theFormatVersion(format_version), fDCFEB(f_dcfeb) {
13  // I may be grabbing too many words, but that's OK
14  // parse for time slices
15  unsigned pos = 0;
16  // to be set later
17  unsigned maxSamples = 8;
18  theSliceStarts.reserve(8);
19  while (theNumberOfSamples < maxSamples) {
20  // first see if it's a bad slice
21  const CSCBadCFEBTimeSlice *badSlice = reinterpret_cast<const CSCBadCFEBTimeSlice *>(buf + pos);
22  if (badSlice->check()) {
23  //show that a bad slice starts here
24  theSliceStarts.push_back(std::pair<int, bool>(pos, false));
25  pos += badSlice->sizeInWords();
26  //store bad word for status digis
27  bWords.push_back(badSlice->word(1).data()); //all 4 words are assumed identical so saving #1 only
28  } else {
29  // OK. Maybe it's good.
30  const CSCCFEBTimeSlice *goodSlice = reinterpret_cast<const CSCCFEBTimeSlice *>(buf + pos);
31  if (goodSlice->check()) {
32  // show that a good slice starts here
33  theSliceStarts.push_back(std::pair<int, bool>(pos, true));
34  // it will just be an array of CSCCFEBTimeSlices, so we'll
35  // grab the number of time slices from the first good one
36  // !!! VB - Limit maximum number of CFEB samples to 8.
37  // !!! In Run2 rare CFEB data corruptions were causing RECO problems with mistakenly setting 16 samples flags
38  // !!! Will need another fix in case of CSC switch to 16 samples readout
39  // maxSamples = goodSlice->sixteenSamples() ? 16 : 8;
40  if (goodSlice->sixteenSamples())
41  LogTrace("CSCCFEBData|CSCRawToDigi")
42  << "CFEB DATA slice " << theNumberOfSamples << " 16 samples flag is detected";
43  pos += goodSlice->sizeInWords();
44  } else {
45  LogTrace("CSCCFEBData|CSCRawToDigi")
46  << "CORRUPT CFEB DATA slice " << theNumberOfSamples << std::hex << " " << *(buf + pos + 3) << " "
47  << *(buf + pos + 2) << " " << *(buf + pos + 1) << " " << *(buf + pos);
48  //ok slice is bad but try another one at 100 words after it
49  theSliceStarts.push_back(std::pair<int, bool>(pos, false));
50  pos += 100;
51  }
52  }
54  }
55  theSize = pos;
56  memcpy(theData, buf, theSize * 2);
57 }
58 
59 CSCCFEBData::CSCCFEBData(unsigned number, bool sixteenSamples, uint16_t format_version, bool f_dcfeb)
60  : boardNumber_(number),
61  theNumberOfSamples(sixteenSamples ? 16 : 8),
62  theFormatVersion(format_version),
63  fDCFEB(f_dcfeb) {
65 
66  // fill the SCA controller words
68  scaWord.ts_flag = sixteenSamples;
69 
70  // make a template slice to copy into theData buffer
72  slice.setControllerWord(scaWord);
73 
74  for (unsigned i = 0; i < theNumberOfSamples; ++i) {
75  unsigned short *pos = theData + i * 100;
76  memcpy(pos, &slice, 200);
77  theSliceStarts.push_back(std::pair<int, bool>(i * 100, true));
78  }
79  theSize = theNumberOfSamples * 100;
80 }
81 
82 void CSCCFEBData::add(const CSCStripDigi &digi, int layer) {
83  std::vector<int> scaCounts = digi.getADCCounts();
84  for (unsigned itime = 0; itime < theNumberOfSamples; ++itime) {
85  unsigned channel = (digi.getStrip() - 1) % 16 + 1;
86  unsigned value = scaCounts[itime] & 0xFFF; // 12-bit
87  // assume it's good, since we're working with simulation
89  assert(slice != nullptr);
90  slice->timeSample(layer, channel, fDCFEB)->adcCounts = value;
92  slice->setCRC();
93  }
94 }
95 
96 const CSCCFEBTimeSlice *CSCCFEBData::timeSlice(unsigned i) const {
97  assert(i < theNumberOfSamples);
98  std::pair<int, bool> start = theSliceStarts[i];
99  // give a NULL pointer if this is a bad slice
100  return start.second ? reinterpret_cast<const CSCCFEBTimeSlice *>(theData + start.first) : nullptr;
101 }
102 
104  assert(i < theNumberOfSamples);
105  std::pair<int, bool> start = theSliceStarts[i];
106  // give a NULL pointer if this is a bad slice
107  return start.second ? reinterpret_cast<CSCCFEBTimeSlice *>(theData + start.first) : nullptr;
108 }
109 
110 unsigned CSCCFEBData::adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const {
111  unsigned result = 0;
112  const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
113  // zero is returned for bad slices
114  if (slice)
115  result = slice->timeSample(layer, channel, fDCFEB)->adcCounts;
116  return result;
117 }
118 unsigned CSCCFEBData::adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const {
119  unsigned result = 0;
120  const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
121  // zero is returned for bad slices
122  if (slice)
123  result = slice->timeSample(layer, channel, fDCFEB)->adcOverflow;
124  return result;
125 }
126 
127 unsigned CSCCFEBData::controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const {
128  // The argument notation is
129  // uglay = un-Gray Coded layer index 1-6
130  // ugchan = un-Gray Coded channel index 1-16
131  // The point being that the SCAC is serially encoded directly in the data stream (without Gray Coding)
132  // so the layer and channel indexes here are just the direct ordering into the data stream.
133 
134  unsigned result = 0;
135  const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
136  // zero is returned for bad slices
137  if (slice)
138  result = slice->timeSample((ugchan - 1) * 6 + uglay - 1)->controllerData;
139  return result;
140 }
141 
142 unsigned CSCCFEBData::overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const {
143  unsigned result = 0;
144  const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
145  // zero is returned for bad slices
146  if (slice)
147  result = slice->timeSample(layer, channel, fDCFEB)->overlappedSampleFlag;
148  return result;
149 }
150 unsigned CSCCFEBData::errorstat(unsigned layer, unsigned channel, unsigned timeBin) const {
151  unsigned result = 0;
152  const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
153  // zero is returned for bad slices
154  if (slice)
155  result = slice->timeSample(layer, channel, fDCFEB)->errorstat;
156  return result;
157 }
158 
159 void CSCCFEBData::setL1A(unsigned l1a) {
160  for (unsigned i = 0; i < theNumberOfSamples; i++)
161  setL1A(i, l1a);
162 }
163 
164 void CSCCFEBData::setL1A(unsigned i, unsigned l1a) {
165  assert(i < theNumberOfSamples);
166  std::pair<int, bool> start = theSliceStarts[i];
167  // give a NULL pointer if this is a bad slice
168  if (start.second) {
169  (reinterpret_cast<CSCCFEBTimeSlice *>(theData + start.first))->set_L1Anumber(l1a);
170  }
171 }
172 
177 
178  std::vector<uint16_t> crcWords(nTimeSamples());
179  std::vector<uint16_t> contrWords(nTimeSamples());
180 
181  if (nTimeSamples() == 0) {
182  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
183  } else {
184  for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
185  const CSCCFEBTimeSlice *slice = timeSlice(itime);
186  // zero is returned for bad slices
187  if (slice)
188  crcWords[itime] = slice->get_crc();
189  if (slice) {
190  int layer = 1;
191  for (unsigned i = 0; i < 16; ++i) {
192  contrWords[itime] |= slice->timeSample(i * 6 + layer - 1)->controllerData << i;
193  }
194  }
195  }
196  }
197 
198  CSCCFEBStatusDigi result(boardNumber_ + 1, crcWords, contrWords, bWords);
199  return result;
200 }
201 
202 void CSCCFEBData::digis(uint32_t idlayer, std::vector<CSCStripDigi> &result) const {
203  // assert(layer>0 && layer <= 6);
204 
205  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
206  if (nTimeSamples() == 0) {
207  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
208  return;
209  }
210 
211  result.reserve(16);
212 
213  std::vector<int> sca(nTimeSamples());
214  std::vector<uint16_t> overflow(nTimeSamples());
215  std::vector<uint16_t> overlap(nTimeSamples());
216  std::vector<uint16_t> errorfl(nTimeSamples());
217 
218  bool me1a = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 4);
219  bool zplus = (CSCDetId::endcap(idlayer) == 1);
220  bool me1b = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 1);
221 
222  unsigned layer = CSCDetId::layer(idlayer);
223 
224  std::vector<uint16_t> l1a_phase(nTimeSamples());
225  for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
226  l1a_phase[itime] = controllerData(layer, 13, itime); // will be zero if timeslice bad
227  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
228  << " l1a_phase = " << controllerData(layer, 13, itime);
229  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
230  << " lct_phase = " << controllerData(layer, 14, itime);
231  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
232  << " # samples = " << controllerData(layer, 16, itime);
233  };
234 
235  for (unsigned ichannel = 1; ichannel <= 16; ++ichannel) {
236  // What is the point of testing here? Move it outside this loop
237  // if (nTimeSamples()==0)
238  // {
239  // LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
240  // break;
241  // }
242 
243  for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
244  const CSCCFEBTimeSlice *slice = timeSlice(itime);
245  if (slice) {
247  word = slice->timeSample(layer, ichannel, fDCFEB);
248  if (word) {
249  sca[itime] = word->adcCounts;
250  overflow[itime] = word->adcOverflow;
251  overlap[itime] = word->overlappedSampleFlag;
252  errorfl[itime] = word->errorstat;
253 
254  // Stick the l1a_phase bit into 'overlap' too (so we can store it in CSCStripDigi
255  // without changing CSCStripDigi format).
256  // Put it in the 9th bit of the overlap word which is only 1-bit anyway.
257  overlap[itime] = ((l1a_phase[itime] & 0x1) << 8) | (word->overlappedSampleFlag & 0x1);
258  }
259  }
260  }
261  if (sca.empty()) {
262  LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
263  break;
264  }
265  int strip = ichannel + 16 * boardNumber_;
266 
267  if (theFormatVersion == 2013) {
268 
269  if (me1a)
270  strip = strip % 64; // reset 65-112/ to 1-48 digi
271  if (me1a && zplus) {
272  strip = 49 - strip;
273  } // 1-48 -> 48-1
274  if (me1b && !zplus) {
275  strip = 65 - strip;
276  } // 1-64 -> 64-1 ...
277 
278  } else { // Handle original 2005 format
279 
280  if (me1a)
281  strip = strip % 64; // reset 65-80 to 1-16 digi
282  if (me1a && zplus) {
283  strip = 17 - strip;
284  } // 1-16 -> 16-1
285  if (me1b && !zplus) {
286  strip = 65 - strip;
287  } // 1-64 -> 64-1 ...
288  }
289  result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
290  }
291 }
292 
293 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer) const {
294  //assert(layer>0 && layer <= 6);
295  std::vector<CSCStripDigi> result;
296  uint32_t layer = idlayer;
297  digis(layer, result);
298  return result;
299 }
300 
301 bool CSCCFEBData::check() const {
302  bool result = true;
303  for (unsigned i = 0; i < theNumberOfSamples; ++i) {
304  const CSCCFEBTimeSlice *slice = timeSlice(i);
305  if (slice == nullptr || !timeSlice(i)->check())
306  result = false;
307  }
308  return result;
309 }
310 
311 std::ostream &operator<<(std::ostream &os, const CSCCFEBData &data) {
312  os << "printing CFEB data sample by sample " << std::endl;
313  for (unsigned ilayer = 1; ilayer <= 6; ++ilayer) {
314  for (unsigned channel = 1; channel <= 16; ++channel) {
315  unsigned strip = channel + data.boardNumber_ * 16;
316  os << "Strip " << strip << " ";
317  for (unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin) {
318  os << data.adcCounts(ilayer, channel, timeBin) << " ";
319  }
320  os << std::endl;
321  }
322  }
323  return os;
324 }
325 
326 std::vector<std::vector<CSCStripDigi> > CSCCFEBData::stripDigis() {
327  std::vector<std::vector<CSCStripDigi> > result;
328  for (int layer = 1; layer <= 6; ++layer) {
329  result.push_back(digis(layer));
330  }
331  return result;
332 }
Definition: start.py:1
unsigned adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:118
unsigned overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:142
std::vector< int > const & getADCCounts() const
Get ADC readings.
Definition: CSCStripDigi.h:44
unsigned short adcOverflow
unsigned sizeInWords() const
void add(const CSCStripDigi &, int layer)
Definition: CSCCFEBData.cc:82
void setL1A(unsigned l1a)
Definition: CSCCFEBData.cc:159
bool sixteenSamples() const
whether we keep 8 or 16 time samples
unsigned adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:110
void setControllerWord(const CSCCFEBSCAControllerWord &controllerWord)
unsigned errorstat(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:150
CSCCFEBStatusDigi statusDigi() const
returns one status digi per cfeb
Definition: CSCCFEBData.cc:173
unsigned get_crc() const
accessors for words 97, 98 and 99
unsigned sizeInWords() const
int layer() const
Definition: CSCDetId.h:56
std::vector< std::pair< int, bool > > theSliceStarts
Definition: CSCCFEBData.h:66
int theSize
in words
Definition: CSCCFEBData.h:68
bool check() const
makes sure each time slice has a trailer
Definition: CSCCFEBData.cc:301
int getStrip() const
Definition: CSCStripDigi.h:41
unsigned controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const
Definition: CSCCFEBData.cc:127
const CSCCFEBTimeSlice * timeSlice(unsigned i) const
count from 0. User should check if it&#39;s a bad slice
Definition: CSCCFEBData.cc:96
int endcap() const
Definition: CSCDetId.h:85
unsigned nTimeSamples() const
Definition: CSCCFEBData.h:20
uint64_t word
uint16_t * data()
Definition: CSCCFEBData.h:45
void digis(uint32_t idlayer, std::vector< CSCStripDigi > &result) const
faster way to get to digis
Definition: CSCCFEBData.cc:202
std::vector< std::vector< CSCStripDigi > > stripDigis()
deprecated. Use the above method.
Definition: CSCCFEBData.cc:326
CSCCFEBDataWord * timeSample(int index) const
input from 0 to 95
unsigned short overlappedSampleFlag
std::vector< uint16_t > bWords
Definition: CSCCFEBData.h:71
Definition: value.py:1
friend std::ostream & operator<<(std::ostream &os, const CSCCFEBData &)
Definition: CSCCFEBData.cc:311
#define LogTrace(id)
unsigned short controllerData
combined from all 16 strips to make a word
int ring() const
Definition: CSCDetId.h:68
unsigned data() const
bool check() const
uint16_t theData[1600]
Definition: CSCCFEBData.h:63
uint16_t theFormatVersion
Definition: CSCCFEBData.h:72
const CSCBadCFEBWord & word(int i) const
count from zero
int station() const
Definition: CSCDetId.h:79
CSCCFEBData(unsigned boardNumber, const uint16_t *buf, uint16_t theFormatVersion=2005, bool fDCFEB=false)
read from an existing data stream.
Definition: CSCCFEBData.cc:11
unsigned short adcCounts
void setCRC()
=VB= Set calculated CRC value for simulated CFEB Time Slice data
unsigned short errorstat
unsigned boardNumber_
Definition: CSCCFEBData.h:69
unsigned theNumberOfSamples
Definition: CSCCFEBData.h:70