CMS 3D CMS Logo

CSCCFEBData.cc
Go to the documentation of this file.
1 
9 #include <cassert>
10 
11 CSCCFEBData::CSCCFEBData(unsigned number, unsigned short * 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  CSCBadCFEBTimeSlice * badSlice
22  = reinterpret_cast<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  CSCCFEBTimeSlice * goodSlice
33  = reinterpret_cast<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  const CSCCFEBTimeSlice * slice = timeSlice(itime);
94  assert(slice != 0);
95  slice->timeSample(layer, channel,fDCFEB)->adcCounts = value;
97  ((CSCCFEBTimeSlice *)slice)->setCRC();
98  }
99 }
100 
101 const CSCCFEBTimeSlice * CSCCFEBData::timeSlice(unsigned i) const
102 {
103  const CSCCFEBTimeSlice * result;
104  assert(i < theNumberOfSamples);
105  std::pair<int,bool> start = theSliceStarts[i];
106  // give a NULL pointer if this is a bad slice
107  if(!start.second)
108  {
109  result = 0;
110  }
111  else
112  {
113  result = reinterpret_cast<const CSCCFEBTimeSlice *>(theData+start.first);
114  }
115  return result;
116 }
117 
118 
119 unsigned CSCCFEBData::adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const
120 {
121  unsigned result = 0;
122  const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
123  // zero is returned for bad slices
124  if(slice) result = slice->timeSample(layer, channel,fDCFEB)->adcCounts;
125  return result;
126 }
127 unsigned CSCCFEBData::adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const
128 {
129  unsigned result = 0;
130  const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
131  // zero is returned for bad slices
132  if(slice) result = slice->timeSample(layer, channel,fDCFEB)->adcOverflow;
133  return result;
134 }
135 
136 unsigned CSCCFEBData::controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const
137 {
138 
139 // The argument notation is
140 // uglay = un-Gray Coded layer index 1-6
141 // ugchan = un-Gray Coded channel index 1-16
142 // The point being that the SCAC is serially encoded directly in the data stream (without Gray Coding)
143 // so the layer and channel indexes here are just the direct ordering into the data stream.
144 
145  unsigned result = 0;
146  const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
147  // zero is returned for bad slices
148  if(slice) result = slice->timeSample( (ugchan-1)*6+uglay-1 )->controllerData;
149  return result;
150 }
151 
152 unsigned CSCCFEBData::overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const
153 {
154  unsigned result = 0;
155  const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
156  // zero is returned for bad slices
157  if(slice) result = slice->timeSample(layer, channel,fDCFEB)->overlappedSampleFlag;
158  return result;
159 }
160 unsigned CSCCFEBData::errorstat(unsigned layer, unsigned channel, unsigned timeBin) const
161 {
162  unsigned result = 0;
163  const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
164  // zero is returned for bad slices
165  if(slice) result = slice->timeSample(layer, channel,fDCFEB)->errorstat;
166  return result;
167 }
168 
169 
170 void CSCCFEBData::setL1A(unsigned l1a)
171 {
172  for (unsigned i=0; i < theNumberOfSamples; i++) setL1A(i, l1a);
173 }
174 
175 void CSCCFEBData::setL1A(unsigned i, unsigned l1a)
176 {
177  assert(i < theNumberOfSamples);
178  std::pair<int,bool> start = theSliceStarts[i];
179  // give a NULL pointer if this is a bad slice
180  if(start.second)
181  {
182  (reinterpret_cast<CSCCFEBTimeSlice *>(theData+start.first))->set_L1Anumber(l1a);
183  }
184 }
185 
187 {
191 
192  std::vector<uint16_t> crcWords(nTimeSamples());
193  std::vector<uint16_t> contrWords(nTimeSamples());
194 
195  if (nTimeSamples()==0)
196  {
197  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
198  }
199  else
200  {
201  for(unsigned itime = 0; itime < nTimeSamples(); ++itime) {
202  const CSCCFEBTimeSlice * slice = timeSlice(itime);
203  // zero is returned for bad slices
204  if (slice) crcWords[itime] = slice->get_crc();
205  if (slice)
206  {
207  int layer=1;
208  for(unsigned i = 0; i < 16; ++i)
209  {
210  contrWords[itime] |= slice->timeSample(i*6+layer-1)->controllerData << i;
211  }
212  }
213 
214  }
215  }
216 
217  CSCCFEBStatusDigi result(boardNumber_+1, crcWords, contrWords, bWords);
218  return result;
219 }
220 
221 
222 
223 void CSCCFEBData::digis(uint32_t idlayer, std::vector<CSCStripDigi> & result )
224 {
225 
226  // assert(layer>0 && layer <= 6);
227 
228  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
229  if (nTimeSamples()==0) {
230  LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
231  return;
232  }
233 
234  result.reserve(16);
235 
236  std::vector<int> sca(nTimeSamples());
237  std::vector<uint16_t> overflow(nTimeSamples());
238  std::vector<uint16_t> overlap(nTimeSamples());
239  std::vector<uint16_t> errorfl(nTimeSamples());
240 
241  bool me1a = (CSCDetId::station(idlayer)==1) && (CSCDetId::ring(idlayer)==4);
242  bool zplus = (CSCDetId::endcap(idlayer) == 1);
243  bool me1b = (CSCDetId::station(idlayer)==1) && (CSCDetId::ring(idlayer)==1);
244 
245  unsigned layer = CSCDetId::layer(idlayer);
246 
247  std::vector<uint16_t> l1a_phase(nTimeSamples());
248  for(unsigned itime = 0; itime < nTimeSamples(); ++itime) {
249  l1a_phase[itime] = controllerData(layer, 13, itime); // will be zero if timeslice bad
250  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " l1a_phase = " << controllerData(layer, 13, itime);
251  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " lct_phase = " << controllerData(layer, 14, itime);
252  LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " # samples = " << controllerData(layer, 16, itime);
253  };
254 
255  for(unsigned ichannel = 1; ichannel <= 16; ++ichannel)
256  {
257  // What is the point of testing here? Move it outside this loop
258  // if (nTimeSamples()==0)
259  // {
260  // LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
261  // break;
262  // }
263 
264  for(unsigned itime = 0; itime < nTimeSamples(); ++itime)
265  {
266  const CSCCFEBTimeSlice * slice = timeSlice(itime);
267  if (slice)
268  {
269  CSCCFEBDataWord * word;
270  word = slice->timeSample(layer, ichannel,fDCFEB);
271  if (word)
272  {
273  sca[itime] = word->adcCounts;
274  overflow[itime] = word->adcOverflow;
275  overlap[itime] = word->overlappedSampleFlag;
276  errorfl[itime] = word->errorstat;
277 
278  // Stick the l1a_phase bit into 'overlap' too (so we can store it in CSCStripDigi
279  // without changing CSCStripDigi format).
280  // Put it in the 9th bit of the overlap word which is only 1-bit anyway.
281  overlap[itime] = (( l1a_phase[itime] & 0x1 ) << 8 ) | ( word->overlappedSampleFlag & 0x1 );
282  }
283  }
284  }
285  if (sca.empty())
286  {
287  LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
288  break;
289  }
290  int strip = ichannel + 16*boardNumber_;
291 
292  if (theFormatVersion == 2013) {
293 
294  if ( me1a ) strip = strip%64; // reset 65-112/ to 1-48 digi
295  if ( me1a && zplus ) { strip = 49 - strip; } // 1-48 -> 48-1
296  if ( me1b && !zplus) { strip = 65 - strip;} // 1-64 -> 64-1 ...
297 
298  } else { // Handle original 2005 format
299 
300  if ( me1a ) strip = strip%64; // reset 65-80 to 1-16 digi
301  if ( me1a && zplus ) { strip = 17 - strip; } // 1-16 -> 16-1
302  if ( me1b && !zplus) { strip = 65 - strip;} // 1-64 -> 64-1 ...
303  }
304  result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
305  }
306 }
307 
308 
309 
310 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer)
311 {
312  //assert(layer>0 && layer <= 6);
313  std::vector<CSCStripDigi> result;
314  uint32_t layer= idlayer;
315  digis(layer, result);
316  return result;
317 }
318 
319 
320 
321 bool CSCCFEBData::check() const
322 {
323  bool result = true;
324  for(unsigned i = 0; i < theNumberOfSamples; ++i)
325  {
326  const CSCCFEBTimeSlice * slice = timeSlice(i);
327  if(slice==0 || !timeSlice(i)->check()) result = false;
328  }
329  return result;
330 }
331 
332 std::ostream & operator<<(std::ostream & os, const CSCCFEBData & data)
333 {
334  os << "printing CFEB data sample by sample " << std::endl;
335  for(unsigned ilayer = 1; ilayer <= 6; ++ilayer)
336  {
337  for(unsigned channel = 1; channel <= 16; ++channel)
338  {
339  unsigned strip = channel + data.boardNumber_*16;
340  os << "Strip " << strip << " ";
341  for(unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin)
342  {
343  os << data.adcCounts(ilayer, channel, timeBin) << " " ;
344  }
345  os << std::endl;
346  }
347  }
348  return os;
349 }
350 
351 std::vector < std::vector<CSCStripDigi> > CSCCFEBData::stripDigis()
352 {
353  std::vector < std::vector<CSCStripDigi> > result;
354  for (int layer = 1; layer <= 6; ++layer)
355  {
356  result.push_back(digis(layer));
357  }
358  return result;
359 }
360 
Definition: start.py:1
unsigned adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:127
unsigned overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:152
unsigned short * data()
Definition: CSCCFEBData.h:46
std::vector< int > const & getADCCounts() const
Get ADC readings.
Definition: CSCStripDigi.h:54
unsigned short adcOverflow
void digis(uint32_t idlayer, std::vector< CSCStripDigi > &result)
faster way to get to digis
Definition: CSCCFEBData.cc:223
unsigned sizeInWords() const
void add(const CSCStripDigi &, int layer)
Definition: CSCCFEBData.cc:85
void setL1A(unsigned l1a)
Definition: CSCCFEBData.cc:170
unsigned adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:119
void setControllerWord(const CSCCFEBSCAControllerWord &controllerWord)
unsigned errorstat(unsigned layer, unsigned channel, unsigned timeBin) const
Definition: CSCCFEBData.cc:160
std::vector< std::pair< int, bool > > theSliceStarts
Definition: CSCCFEBData.h:66
CSCCFEBStatusDigi statusDigi() const
returns one status digi per cfeb
Definition: CSCCFEBData.cc:186
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:68
bool check() const
makes sure each time slice has a trailer
Definition: CSCCFEBData.cc:321
int getStrip() const
Definition: CSCStripDigi.h:51
unsigned controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const
Definition: CSCCFEBData.cc:136
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
unsigned short theData[1600]
Definition: CSCCFEBData.h:63
int endcap() const
Definition: CSCDetId.h:93
unsigned nTimeSamples() const
Definition: CSCCFEBData.h:21
CSCBadCFEBWord & word(int i)
count from zero
std::vector< std::vector< CSCStripDigi > > stripDigis()
deprecated. Use the above method.
Definition: CSCCFEBData.cc:351
bool sixteenSamples()
whether we keep 8 or 16 time samples
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:332
#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
CSCCFEBData(unsigned boardNumber, unsigned short *buf, uint16_t theFormatVersion=2005, bool fDCFEB=false)
read from an existing data stream.
Definition: CSCCFEBData.cc:11
uint16_t theFormatVersion
Definition: CSCCFEBData.h:72
int station() const
Definition: CSCDetId.h:86
unsigned short adcCounts
unsigned short errorstat
unsigned boardNumber_
Definition: CSCCFEBData.h:69
unsigned theNumberOfSamples
Definition: CSCCFEBData.h:70