CMS 3D CMS Logo

CSCCFEBData.cc
Go to the documentation of this file.
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  }
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 {
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 
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) {
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  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
204  if (nTimeSamples() == 0) {
205  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
206  return;
207  }
208 
209  result.reserve(16);
210 
211  std::vector<int> sca(nTimeSamples());
212  std::vector<uint16_t> overflow(nTimeSamples());
213  std::vector<uint16_t> overlap(nTimeSamples());
214  std::vector<uint16_t> errorfl(nTimeSamples());
215 
216  bool me1a = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 4);
217  bool zplus = (CSCDetId::endcap(idlayer) == 1);
218  bool me1b = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 1);
219 
220  unsigned layer = CSCDetId::layer(idlayer);
221 
222  std::vector<uint16_t> l1a_phase(nTimeSamples());
223  for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
224  l1a_phase[itime] = controllerData(layer, 13, itime); // will be zero if timeslice bad
225  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
226  << " l1a_phase = " << controllerData(layer, 13, itime);
227  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
228  << " lct_phase = " << controllerData(layer, 14, itime);
229  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
230  << " # samples = " << controllerData(layer, 16, itime);
231  };
232 
233  for (unsigned ichannel = 1; ichannel <= 16; ++ichannel) {
234  // What is the point of testing here? Move it outside this loop
235  // if (nTimeSamples()==0)
236  // {
237  // LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
238  // break;
239  // }
240 
241  for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
242  const CSCCFEBTimeSlice *slice = timeSlice(itime);
243  if (slice) {
245  word = slice->timeSample(layer, ichannel, fDCFEB);
246  if (word) {
247  sca[itime] = word->adcCounts;
248  overflow[itime] = word->adcOverflow;
249  overlap[itime] = word->overlappedSampleFlag;
250  errorfl[itime] = word->errorstat;
251 
252  // Stick the l1a_phase bit into 'overlap' too (so we can store it in CSCStripDigi
253  // without changing CSCStripDigi format).
254  // Put it in the 9th bit of the overlap word which is only 1-bit anyway.
255  overlap[itime] = ((l1a_phase[itime] & 0x1) << 8) | (word->overlappedSampleFlag & 0x1);
256  }
257  }
258  }
259  if (sca.empty()) {
260  LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
261  break;
262  }
263  int strip = ichannel + 16 * boardNumber_;
264 
265  if (theFormatVersion >= 2013) {
266 
267  if (me1a)
268  strip = strip % CSCConstants::NUM_STRIPS_ME1B; // reset 65-112/ to 1-48 digi
269  if (me1a && zplus) {
271  } // 1-48 -> 48-1
272  if (me1b && !zplus) {
274  } // 1-64 -> 64-1 ...
275 
276  } else { // Handle original 2005 format
277 
278  if (me1a)
279  strip = strip % CSCConstants::NUM_STRIPS_ME1B; // reset 65-80 to 1-16 digi
280  if (me1a && zplus) {
282  } // 1-16 -> 16-1
283  if (me1b && !zplus) {
285  } // 1-64 -> 64-1 ...
286  }
287  result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
288  }
289 }
290 
291 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer) const {
292  std::vector<CSCStripDigi> result;
293  uint32_t layer = idlayer;
294  digis(layer, result);
295  return result;
296 }
297 
298 bool CSCCFEBData::check() const {
299  bool result = true;
300  for (unsigned i = 0; i < theNumberOfSamples; ++i) {
301  const CSCCFEBTimeSlice *slice = timeSlice(i);
302  if (slice == nullptr || !timeSlice(i)->check())
303  result = false;
304  }
305  return result;
306 }
307 
308 std::ostream &operator<<(std::ostream &os, const CSCCFEBData &data) {
309  os << "printing CFEB data sample by sample " << std::endl;
310  for (int ilayer = CSCDetId::minLayerId(); ilayer <= CSCDetId::maxLayerId(); ++ilayer) {
311  for (unsigned channel = 1; channel <= 16; ++channel) {
312  unsigned strip = channel + data.boardNumber_ * 16;
313  os << "Strip " << strip << " ";
314  for (unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin) {
315  os << data.adcCounts(ilayer, channel, timeBin) << " ";
316  }
317  os << std::endl;
318  }
319  }
320  return os;
321 }
322 
323 std::vector<std::vector<CSCStripDigi> > CSCCFEBData::stripDigis() {
324  std::vector<std::vector<CSCStripDigi> > result;
326  result.push_back(digis(layer));
327  }
328  return result;
329 }
Definition: start.py:1
CSCCFEBStatusDigi statusDigi() const
returns one status digi per cfeb
Definition: CSCCFEBData.cc:173
unsigned sizeInWords() const
unsigned controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const
Definition: CSCCFEBData.cc:127
void add(const CSCStripDigi &, int layer)
Definition: CSCCFEBData.cc:82
void setL1A(unsigned l1a)
Definition: CSCCFEBData.cc:159
std::ostream & operator<<(std::ostream &os, const CSCCFEBData &data)
Definition: CSCCFEBData.cc:308
int layer() const
Definition: CSCDetId.h:56
unsigned adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:110
assert(be >=bs)
std::vector< std::pair< int, bool > > theSliceStarts
Definition: CSCCFEBData.h:66
int getStrip() const
Definition: CSCStripDigi.h:41
int theSize
in words
Definition: CSCCFEBData.h:68
#define LogTrace(id)
unsigned data() const
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
unsigned sizeInWords() const
uint64_t word
std::vector< std::vector< CSCStripDigi > > stripDigis()
deprecated. Use the above method.
Definition: CSCCFEBData.cc:323
bool sixteenSamples() const
whether we keep 8 or 16 time samples
unsigned overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:142
std::vector< uint16_t > bWords
Definition: CSCCFEBData.h:71
Definition: value.py:1
unsigned errorstat(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:150
unsigned adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:118
bool check() const
static int minLayerId()
Definition: CSCDetId.h:242
int station() const
Definition: CSCDetId.h:79
const CSCBadCFEBWord & word(int i) const
count from zero
constexpr int maxSamples
Definition: HcalConstants.h:6
int endcap() const
Definition: CSCDetId.h:85
unsigned nTimeSamples() const
Definition: CSCCFEBData.h:20
void digis(uint32_t idlayer, std::vector< CSCStripDigi > &result) const
faster way to get to digis
Definition: CSCCFEBData.cc:202
uint16_t theData[1600]
Definition: CSCCFEBData.h:63
const CSCCFEBTimeSlice * timeSlice(unsigned i) const
count from 0. User should check if it&#39;s a bad slice
Definition: CSCCFEBData.cc:96
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
uint16_t theFormatVersion
Definition: CSCCFEBData.h:72
CSCCFEBData(unsigned boardNumber, const uint16_t *buf, uint16_t theFormatVersion=2005, bool fDCFEB=false)
read from an existing data stream.
Definition: CSCCFEBData.cc:11
int ring() const
Definition: CSCDetId.h:68
bool check() const
makes sure each time slice has a trailer
Definition: CSCCFEBData.cc:298
static int maxLayerId()
Definition: CSCDetId.h:243
std::vector< int > const & getADCCounts() const
Get ADC readings.
Definition: CSCStripDigi.h:47
unsigned boardNumber_
Definition: CSCCFEBData.h:69
unsigned theNumberOfSamples
Definition: CSCCFEBData.h:70