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