CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CSCComparatorData.cc
Go to the documentation of this file.
6 #include <iostream>
7 #include <cstdio>
8 #include <cstring>
9 
10 #ifdef LOCAL_UNPACK
11 bool CSCComparatorData::debug = false;
12 #else
13 #include <atomic>
14 std::atomic<bool> CSCComparatorData::debug{false};
15 #endif
16 
18  : ncfebs_(tmbHeader->NCFEBs()), ntbins_(tmbHeader->NTBins()) {
19  if (tmbHeader != nullptr)
20  theFirmwareVersion = tmbHeader->FirmwareVersion();
21  else
22  theFirmwareVersion = 2007;
23  size_ = nlines();
24  zero();
25 }
26 
27 CSCComparatorData::CSCComparatorData(int ncfebs, int ntbins, int firmware_version)
28  : ncfebs_(ncfebs), ntbins_(ntbins), theFirmwareVersion(firmware_version) {
29  size_ = nlines();
30  zero();
31 }
32 
33 CSCComparatorData::CSCComparatorData(int ncfebs, int ntbins, const unsigned short* buf, int firmware_version)
34  : ncfebs_(ncfebs), ntbins_(ntbins), theFirmwareVersion(firmware_version) {
35  // add two more for odd ntbins, plus one for the e0c
36  // Oct 2004 Rick: e0c line belongs to CSCTMBTrailer
37  size_ = (nlines() % 2 == 1) ? nlines() + 2 : nlines();
38 
39  memcpy(theData, buf, size_ * 2);
40 }
41 
43  for (int ifeb = 0; ifeb < ncfebs_; ++ifeb) {
44  for (int tbin = 0; tbin < ntbins_; ++tbin) {
46  dataWord(ifeb, tbin, layer) = CSCComparatorDataWord(ifeb, tbin, 0);
47  }
48  }
49  }
50 }
51 
52 std::vector<CSCComparatorDigi> CSCComparatorData::comparatorDigis(uint32_t idlayer, unsigned cfeb) {
53  static const bool doStripSwapping = true;
54  bool me1a = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 4);
55  bool zplus = (CSCDetId::endcap(idlayer) == 1);
56  bool me1b = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 1);
57  int layer = CSCDetId::layer(idlayer);
58 
59  assert(layer >= CSCDetId::minLayerId());
60  assert(layer <= CSCDetId::maxLayerId());
61 
62  //looking for comp output on layer
63  std::vector<CSCComparatorDigi> result;
64 
65  // this is pretty sparse data, so I wish we could check the
66  // data word by word, not bit by bit, but I don't see how to
67  // do the time sequencing that way.
68  for (int distrip = 0; distrip < CSCConstants::NUM_DISTRIPS_PER_CFEB; ++distrip) {
69  uint16_t tbinbitsS0HS0 = 0;
70  uint16_t tbinbitsS0HS1 = 0;
71  uint16_t tbinbitsS1HS0 = 0;
72  uint16_t tbinbitsS1HS1 = 0;
73  for (int tbin = 0; tbin < ntbins_ - 2; ++tbin) {
74  if (bitValue(cfeb, tbin, layer, distrip)) {
76  CSCComparatorDataWord word = dataWord(cfeb, tbin, layer);
77  assert(word.tbin_ == tbin);
78  assert(word.cfeb_ == cfeb);
79  // we have a hit. The next two time samples
80  // are the other two bits in the triad
81  int bit2 = bitValue(cfeb, tbin + 1, layer, distrip);
82  int bit3 = bitValue(cfeb, tbin + 2, layer, distrip);
83  // should count from zero
84  int chamberDistrip = distrip + cfeb * CSCConstants::NUM_DISTRIPS_PER_CFEB;
85  int HalfStrip = 4 * chamberDistrip + bit2 * 2 + bit3;
86  int output = 4 + bit2 * 2 + bit3;
87  /*
88  * Handles distrip logic; comparator output is for pairs of strips:
89  * hit bin dec
90  * x--- 100 4
91  * -x-- 101 5
92  * --x- 110 6
93  * ---x 111 7
94  *
95  */
96 
97  if (debug)
98  LogTrace("CSCComparatorData|CSCRawToDigi")
99  << "fillComparatorOutputs: layer = " << layer << " timebin = " << tbin << " cfeb = " << cfeb
100  << " distrip = " << chamberDistrip << " HalfStrip = " << HalfStrip << " Output " << output << std::endl;
102 
104  if (output == 4)
105  tbinbitsS0HS0 = tbinbitsS0HS0 + (1 << tbin);
106  if (output == 5)
107  tbinbitsS0HS1 = tbinbitsS0HS1 + (1 << tbin);
108  if (output == 6)
109  tbinbitsS1HS0 = tbinbitsS1HS0 + (1 << tbin);
110  if (output == 7)
111  tbinbitsS1HS1 = tbinbitsS1HS1 + (1 << tbin);
112 
113  tbin += 2;
114  }
115  } //end of loop over time bins
116  //we do not have to check over the last couple of time bins if there are no hits since
117  //comparators take 3 time bins
118 
119  // Store digis each of possible four halfstrips for given distrip:
120  if (tbinbitsS0HS0 || tbinbitsS0HS1 || tbinbitsS1HS0 || tbinbitsS1HS1) {
121  unsigned int cfeb_corr = cfeb;
122  unsigned int distrip_corr = distrip;
123 
124  if (doStripSwapping) {
125  // Fix ordering of strips and CFEBs in ME1/1.
126  // SV, 27/05/08: keep CFEB=4 for ME1/a until CLCT trigger logic
127  // stops combining it with the info from the other 4 CFEBs (ME1/b).
128  //
129  if (theFirmwareVersion >= 2013) {
130  if (me1a && zplus) {
131  distrip_corr = 7 - distrip; // 0-7 -> 7-0
132  cfeb_corr = 10 - cfeb;
133  }
134  if (me1b && !zplus) {
135  distrip_corr = 7 - distrip;
136  cfeb_corr = 3 - cfeb;
137  }
138  } else {
139  // if ( me1a ) { cfeb_corr = 0; } // reset 4 to 0
140  if (me1a && zplus) {
141  distrip_corr = 7 - distrip; // 0-7 -> 7-0
142  }
143  if (me1b && !zplus) {
144  distrip_corr = 7 - distrip;
145  cfeb_corr = 3 - cfeb;
146  }
147  }
148  }
149 
150  int strip = 16 * cfeb_corr + 2 * distrip_corr + 1;
151 
152  if (debug)
153  LogTrace("CSCComparatorData|CSCRawToDigi") << "fillComparatorOutputs: cfeb_corr = " << cfeb_corr
154  << " distrip_corr = " << distrip_corr << " strip = " << strip;
155 
156  if (doStripSwapping && ((me1a && zplus) || (me1b && !zplus))) {
157  // Half-strips need to be flipped too.
158  if (tbinbitsS1HS1)
159  result.push_back(CSCComparatorDigi(strip, 0, tbinbitsS1HS1));
160  if (tbinbitsS1HS0)
161  result.push_back(CSCComparatorDigi(strip, 1, tbinbitsS1HS0));
162  if (tbinbitsS0HS1)
163  result.push_back(CSCComparatorDigi(strip + 1, 0, tbinbitsS0HS1));
164  if (tbinbitsS0HS0)
165  result.push_back(CSCComparatorDigi(strip + 1, 1, tbinbitsS0HS0));
166  } else {
167  if (tbinbitsS0HS0)
168  result.push_back(CSCComparatorDigi(strip, 0, tbinbitsS0HS0));
169  if (tbinbitsS0HS1)
170  result.push_back(CSCComparatorDigi(strip, 1, tbinbitsS0HS1));
171  if (tbinbitsS1HS0)
172  result.push_back(CSCComparatorDigi(strip + 1, 0, tbinbitsS1HS0));
173  if (tbinbitsS1HS1)
174  result.push_back(CSCComparatorDigi(strip + 1, 1, tbinbitsS1HS1));
175  }
176  //uh oh ugly ugly ugly!
177  }
178  } //end of loop over distrips
179  return result;
180 }
181 
182 std::vector<CSCComparatorDigi> CSCComparatorData::comparatorDigis(int layer) {
183  assert(layer >= CSCDetId::minLayerId());
184  assert(layer <= CSCDetId::maxLayerId());
185 
186  std::vector<CSCComparatorDigi> result;
187  for (int cfeb = 0; cfeb < ncfebs_; ++cfeb) {
188  std::vector<CSCComparatorDigi> oneCfebDigi = comparatorDigis(layer, cfeb);
189  result.insert(result.end(), oneCfebDigi.begin(), oneCfebDigi.end());
190  }
191 
192  return result;
193 }
194 
196  int strip = digi.getStrip();
197  int halfstrip = digi.getHalfStrip();
198  int cfeb = digi.getCFEB();
199  int distrip = digi.getDiStrip();
200 
201  // Check the distrip and half-strip number
204  // note that half-strips are not staggered in the packer
206 
207  std::vector<int> timeBinsOn = digi.getTimeBinsOn();
208  for (std::vector<int>::const_iterator tbinItr = timeBinsOn.begin(); tbinItr != timeBinsOn.end(); ++tbinItr) {
209  int tbin = *tbinItr;
210  if (tbin >= 0 && tbin < ntbins_ - 2) {
211  // First triad bit indicates the presence of the hit
212  dataWord(cfeb, tbin, layer).set(distrip, true);
213  // Second bit indicates which of the two strips contains the hit
214  if (strip % 2 == 0)
215  dataWord(cfeb, tbin + 1, layer).set(distrip, true);
216  // Third bit indicates whether the hit is located on the left or on the
217  // right side of the strip.
218  if (digi.getComparator())
219  dataWord(cfeb, tbin + 2, layer).set(distrip, true);
220  }
221  }
222 }
223 
224 /***
225  * Comparator packing version with ME11 strips swapping
226  ***/
227 void CSCComparatorData::add(const CSCComparatorDigi& digi, const CSCDetId& cid) {
228  static const bool doStripSwapping = true;
229  bool me1a = (cid.station() == 1) && (cid.ring() == 4);
230  bool zplus = (cid.endcap() == 1);
231  bool me1b = (cid.station() == 1) && (cid.ring() == 1);
232 
233  unsigned layer = cid.layer();
234 
235  int strip = digi.getStrip();
236  int halfstrip = digi.getHalfStrip();
237  int cfeb = digi.getCFEB();
238  int distrip = digi.getDiStrip();
239  int bit2 = (strip - 1) % 2;
240  int bit3 = digi.getComparator();
241 
242  // Check the distrip and half-strip number
243  if (theFirmwareVersion >= 2013) {
246  // note that half-strips are not staggered in the packer
248  } else {
251  // note that half-strips are not staggered in the packer
253  }
254 
255  // Lets try to do ME11 strip flipping
256  if (doStripSwapping) {
257  if (theFirmwareVersion >= 2013) {
258  if ((me1a || (me1b && (cfeb > CSCConstants::NUM_CFEBS_ME1A_UNGANGED))) && zplus) {
259  distrip = 7 - distrip; // 0-7 -> 7-0
260  cfeb = 10 - cfeb;
261  bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
262  bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
263  }
264  if (me1b && !zplus && (cfeb < CSCConstants::NUM_CFEBS_ME1B)) {
265  distrip = 7 - distrip;
266  cfeb = 3 - cfeb;
267  bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
268  bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
269  }
270  } else {
271  if ((me1a || (me1b && (cfeb > CSCConstants::NUM_CFEBS_ME1A_UNGANGED))) && zplus) {
272  distrip = 7 - distrip; // 0-7 -> 7-0
273  bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
274  bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
275  }
276  if (me1b && !zplus && (cfeb < CSCConstants::NUM_CFEBS_ME1B)) {
277  distrip = 7 - distrip;
278  cfeb = 3 - cfeb;
279  bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
280  bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
281  }
282  }
283  }
284 
285  std::vector<int> timeBinsOn = digi.getTimeBinsOn();
286  for (std::vector<int>::const_iterator tbinItr = timeBinsOn.begin(); tbinItr != timeBinsOn.end(); ++tbinItr) {
287  int tbin = *tbinItr;
288  if (tbin >= 0 && tbin < ntbins_ - 2) {
289  // First triad bit indicates the presence of the hit
290  dataWord(cfeb, tbin, layer).set(distrip, true);
291  // Second bit indicates which of the two strips contains the hit
292  // if (strip%2 == 0)
293  if (bit2)
294  dataWord(cfeb, tbin + 1, layer).set(distrip, true);
295  // Third bit indicates whether the hit is located on the left or on the
296  // right side of the strip.
297  // if (digi.getComparator())
298  if (bit3)
299  dataWord(cfeb, tbin + 2, layer).set(distrip, true);
300  }
301  }
302 }
303 
305  bool result = true;
306  for (int cfeb = 0; cfeb < ncfebs_; ++cfeb) {
307  for (int tbin = 0; tbin < ntbins_; ++tbin) {
310  const CSCComparatorDataWord& word = dataWord(cfeb, tbin, layer);
311  bool wordIsGood = (word.tbin_ == tbin) && (word.cfeb_ == cfeb);
312  result = result && wordIsGood;
313  if (!wordIsGood && debug) {
314  LogTrace("CSCComparatorData|CSCRawToDigi")
315  << "Bad CLCT data in layer " << layer << " expect CFEB " << cfeb << " tbin " << tbin;
316  LogTrace("CSCComparatorData|CSCRawToDigi") << " See " << word.cfeb_ << " " << word.tbin_;
317  }
318  }
319  }
320  }
321  if (!result)
322  LogTrace("CSCComparatorData|CSCRawToDigi") << "++ Bad CLCT Data ++ ";
323  return result;
324 }
325 
327  for (int i = 0; i < size_; i++) {
328  printf("%04x %04x %04x %04x\n", theData[i + 3], theData[i + 2], theData[i + 1], theData[i]);
329  i += 3;
330  }
331 }
332 
334  CSCComparatorData comparatorData(5, 16);
335  // aim for output 4 in 5th time bin, = 0000000000010000
336  CSCComparatorDigi comparatorDigi1(1, 0, 0x10);
337  // aim for output 5 in 6th time bin, = 0000 0000 0010 0000
338  CSCComparatorDigi comparatorDigi2(39, 1, 0x20);
339  // aim for output 7 in 7th time bin, = 000 0000 0100 0000
340  CSCComparatorDigi comparatorDigi3(80, 1, 0x40);
341 
342  comparatorData.add(comparatorDigi1, 1);
343  comparatorData.add(comparatorDigi2, 4);
344  comparatorData.add(comparatorDigi3, 6);
345 
346  CSCDetId layer1(1, 4, 1, 2, 1);
347  CSCDetId layer4(1, 4, 1, 2, 4);
348  CSCDetId layer6(1, 4, 1, 2, 6);
349 
350  std::vector<CSCComparatorDigi> digis1 = comparatorData.comparatorDigis(1);
351  std::vector<CSCComparatorDigi> digis2 = comparatorData.comparatorDigis(4);
352  std::vector<CSCComparatorDigi> digis3 = comparatorData.comparatorDigis(6);
353 
354  assert(digis1.size() == 1);
355  assert(digis2.size() == 1);
356  assert(digis3.size() == 1);
357 
358  assert(digis1[0].getStrip() == 1);
359  assert(digis1[0].getComparator() == 0);
360  assert(digis1[0].getTimeBin() == 4);
361 
362  assert(digis2[0].getStrip() == 39);
363  assert(digis2[0].getComparator() == 1);
364  assert(digis2[0].getTimeBin() == 5);
365 
366  assert(digis3[0].getStrip() == 80);
367  assert(digis3[0].getComparator() == 1);
368  assert(digis3[0].getTimeBin() == 6);
369 }
int getHalfStrip() const
Get the associated halfstrip number for this comparator digi. Counts from 0.
void set(int distrip, bool value)
@ not right! doesn&#39;t set zero
int getStrip() const
Get the strip number. Counts from 1.
int getCFEB() const
Get the CFEB number. Counts from 0.
bool bitValue(int cfeb, int tbin, int layer, int distrip)
assert(be >=bs)
int getComparator() const
Get Comparator readings. Can be 0 or 1.
int layer() const
Definition: CSCDetId.h:56
static void selfTest()
#define LogTrace(id)
constexpr std::array< uint8_t, layerIndexSize > layer
tuple result
Definition: mps_fire.py:311
int endcap() const
Definition: CSCDetId.h:85
CSCComparatorDataWord & dataWord(int iline) const
uint64_t word
printf("params %d %f %f %f\n", minT, eps, errmax, chi2max)
std::vector< int > getTimeBinsOn() const
int ring() const
Definition: CSCDetId.h:68
static int minLayerId()
Definition: CSCDetId.h:242
void add(const CSCComparatorDigi &digi, int layer)
TODO for packing. Doesn&#39;t do flipping yet.
int getDiStrip() const
Get the distrip number. Counts from 0.
CSCComparatorData(const CSCTMBHeader *tmbHeader)
int FirmwareVersion() const
Definition: CSCTMBHeader.h:40
static std::atomic< bool > debug
int station() const
Definition: CSCDetId.h:79
std::vector< CSCComparatorDigi > comparatorDigis(int layer)
layers count from one
unsigned short theData[7 *6 *32]
static int maxLayerId()
Definition: CSCDetId.h:243