CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
EcalTBDaqFormatter.cc
Go to the documentation of this file.
1 /*
2  *
3  * \author N. Marinelli IASA
4  * \author G. Della Ricca
5  * \author G. Franzoni
6  * \author A. Ghezzi
7  *
8  */
9 
10 #include "EcalTBDaqFormatter.h"
16 
20 
21 #include "DCCDataParser.h"
22 #include "DCCEventBlock.h"
23 #include "DCCTowerBlock.h"
24 #include "DCCTCCBlock.h"
25 #include "DCCXtalBlock.h"
26 #include "DCCDataMapper.h"
27 
28 #include <iostream>
29 
31  LogDebug("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter";
32  std::vector<uint32_t> parameters;
33  parameters.push_back(10); // parameters[0] is the xtal samples
34  parameters.push_back(1); // parameters[1] is the number of trigger time samples for TPG's
35  parameters.push_back(68); // parameters[2] is the number of TT
36  parameters.push_back(68); // parameters[3] is the number of SR Flags
37  parameters.push_back(1); // parameters[4] is the dcc id
38  parameters.push_back(1); // parameters[5] is the sr id
39  parameters.push_back(1); // parameters[6] is the tcc1 id
40  parameters.push_back(2); // parameters[7] is the tcc2 id
41  parameters.push_back(3); // parameters[8] is the tcc3 id
42  parameters.push_back(4); // parameters[9] is the tcc4 id
43 
44  theParser_ = new DCCTBDataParser(parameters);
45 }
46 
48  EBDigiCollection& digicollection,
49  EcalPnDiodeDigiCollection& pndigicollection,
50  EcalRawDataCollection& DCCheaderCollection,
51  EBDetIdCollection& dccsizecollection,
52  EcalElectronicsIdCollection& ttidcollection,
53  EcalElectronicsIdCollection& blocksizecollection,
54  EBDetIdCollection& chidcollection,
55  EBDetIdCollection& gaincollection,
56  EBDetIdCollection& gainswitchcollection,
57  EcalElectronicsIdCollection& memttidcollection,
58  EcalElectronicsIdCollection& memblocksizecollection,
59  EcalElectronicsIdCollection& memgaincollection,
60  EcalElectronicsIdCollection& memchidcollection,
61  EcalTrigPrimDigiCollection& tpcollection) {
62  const unsigned char* pData = fedData.data();
63  int length = fedData.size();
64  bool shit = true;
65  unsigned int tower = 0;
66  int ch = 0;
67  int strip = 0;
68 
69  LogDebug("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::interpretRawData"
70  << "size " << length;
71 
72  // mean + 3sigma estimation needed when switching to 0suppressed data
73  digicollection.reserve(kCrystals);
74  pnAllocated = false;
75 
76  theParser_->parseBuffer(reinterpret_cast<const uint32_t*>(pData), static_cast<uint32_t>(length), shit);
77 
78  std::vector<DCCTBEventBlock*>& dccEventBlocks = theParser_->dccEvents();
79 
80  // Access each DCCTB block
81  for (std::vector<DCCTBEventBlock*>::iterator itEventBlock = dccEventBlocks.begin();
82  itEventBlock != dccEventBlocks.end();
83  itEventBlock++) {
84  bool _displayParserMessages = false;
85  if ((*itEventBlock)->eventHasErrors() && _displayParserMessages) {
86  edm::LogWarning("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::interpretRawData"
87  << "errors found from parser... ";
88  edm::LogWarning("EcalTBRawToDigi") << (*itEventBlock)->eventErrorString();
89  edm::LogWarning("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::interpretRawData"
90  << "... errors from parser notified";
91  }
92 
93  // getting the fields of the DCC header
94  EcalDCCHeaderBlock theDCCheader;
95 
96  theDCCheader.setId(28); // tb unpacker: forced to 28 to get first geom slot in EB
97  int fedId = (*itEventBlock)->getDataField("FED/DCC ID");
98  theDCCheader.setFedId(fedId); // fed id as found in raw data (0... 35 at tb )
99 
100  theDCCheader.setRunNumber((*itEventBlock)->getDataField("RUN NUMBER"));
101  short trigger_type = (*itEventBlock)->getDataField("TRIGGER TYPE");
102  short zs = (*itEventBlock)->getDataField("ZS");
103  short tzs = (*itEventBlock)->getDataField("TZS");
104  short sr = (*itEventBlock)->getDataField("SR");
105  bool dataIsSuppressed;
106 
107  // if zs&&tzs the suppression algo is used in DCC, the data are not suppressed and zs-bits are set
108  if (zs && !(tzs))
109  dataIsSuppressed = true;
110  else
111  dataIsSuppressed = false;
112 
113  if (trigger_type > 0 && trigger_type < 5) {
114  theDCCheader.setBasicTriggerType(trigger_type);
115  } else {
116  edm::LogWarning("EcalTBRawToDigiTriggerType") << "@SUB=EcalTBDaqFormatter::interpretRawData"
117  << "unrecognized TRIGGER TYPE: " << trigger_type;
118  }
119  theDCCheader.setLV1((*itEventBlock)->getDataField("LV1"));
120  theDCCheader.setOrbit((*itEventBlock)->getDataField("ORBIT COUNTER"));
121  theDCCheader.setBX((*itEventBlock)->getDataField("BX"));
122  theDCCheader.setErrors((*itEventBlock)->getDataField("DCC ERRORS"));
123  theDCCheader.setSelectiveReadout(sr);
124  theDCCheader.setZeroSuppression(zs);
125  theDCCheader.setTestZeroSuppression(tzs);
126  theDCCheader.setSrpStatus((*itEventBlock)->getDataField("SR_CHSTATUS"));
127 
128  std::vector<short> theTCCs;
129  for (int i = 0; i < MAX_TCC_SIZE; i++) {
130  char TCCnum[20];
131  sprintf(TCCnum, "TCC_CHSTATUS#%d", i + 1);
132  std::string TCCnumS(TCCnum);
133  theTCCs.push_back((*itEventBlock)->getDataField(TCCnumS));
134  }
135  theDCCheader.setTccStatus(theTCCs);
136 
137  std::vector<DCCTBTCCBlock*> tccBlocks = (*itEventBlock)->tccBlocks();
138 
139  for (std::vector<DCCTBTCCBlock*>::iterator itTCCBlock = tccBlocks.begin(); itTCCBlock != tccBlocks.end();
140  itTCCBlock++) {
141  std::vector<std::pair<int, bool> > TpSamples = (*itTCCBlock)->triggerSamples();
142  // std::vector of 3 bits
143  std::vector<int> TpFlags = (*itTCCBlock)->triggerFlags();
144 
145  // there have always to be 68 primitives and flags, per FED
146  if (TpSamples.size() == 68 && TpFlags.size() == 68) {
147  for (int i = 0; i < ((int)TpSamples.size()); i++) {
148  int etaTT = (i) / kTowersInPhi + 1;
149  int phiTT = (i) % kTowersInPhi + 1;
150 
151  // follow HB convention in iphi
152  phiTT = 3 - phiTT;
153  if (phiTT <= 0)
154  phiTT = phiTT + 72;
155 
156  EcalTriggerPrimitiveSample theSample(TpSamples[i].first, TpSamples[i].second, TpFlags[i]);
157 
158  EcalTrigTowerDetId idtt(1, EcalBarrel, etaTT, phiTT, 0);
159 
160  EcalTriggerPrimitiveDigi thePrimitive(idtt);
161  thePrimitive.setSize(1); // hard coded
162  thePrimitive.setSample(0, theSample);
163 
164  tpcollection.push_back(thePrimitive);
165 
166  LogDebug("EcalTBRawToDigiTpg") << "@SUBS=EcalTBDaqFormatter::interpretRawData"
167  << "tower: " << (i + 1) << " primitive: " << TpSamples[i].first
168  << " flag: " << TpSamples[i].second;
169 
170  LogDebug("EcalTBRawToDigiTpg") << "@SUBS=EcalTBDaqFormatter::interpretRawData"
171  << "tower: " << (i + 1) << " flag: " << TpFlags[i];
172  } // end loop on tower primitives
173 
174  } // end if
175  else {
176  edm::LogWarning("EcalTBRawToDigiTpg")
177  << "68 elements not found for TpFlags or TpSamples, collection will be empty";
178  }
179  }
180 
181  short TowerStatus[MAX_TT_SIZE + 1];
182  char buffer[25];
183  std::vector<short> theTTstatus;
184  for (int i = 1; i < MAX_TT_SIZE + 1; i++) {
185  sprintf(buffer, "FE_CHSTATUS#%d", i);
186  std::string Tower(buffer);
187  TowerStatus[i] = (*itEventBlock)->getDataField(Tower);
188  theTTstatus.push_back(TowerStatus[i]);
189  //std::cout << "tower " << i << " has status " << TowerStatus[i] << std::endl;
190  }
191 
192  theDCCheader.setFEStatus(theTTstatus);
193 
194  EcalDCCTBHeaderRuntypeDecoder theRuntypeDecoder;
195  uint32_t DCCruntype = (*itEventBlock)->getDataField("RUN TYPE");
196  theRuntypeDecoder.Decode(DCCruntype, &theDCCheader);
197  //DCCHeader filled!
198  DCCheaderCollection.push_back(theDCCheader);
199 
200  std::vector<DCCTBTowerBlock*> dccTowerBlocks = (*itEventBlock)->towerBlocks();
201  LogDebug("EcalTBRawToDigi") << "@SUBS=EcalTBDaqFormatter::interpretRawData"
202  << "dccTowerBlocks size " << dccTowerBlocks.size();
203 
204  _expTowersIndex = 0;
205  _numExpectedTowers = 0;
206  for (int v = 0; v < 71; v++) {
207  _ExpectedTowers[v] = 99999;
208  }
209 
210  // note: these are the tower statuses handled at the moment - to be completed
211  // staus==0: tower expected;
212  // staus==9: Synk error LV1, tower expected;
213  // staus==10: Synk error BX, tower expected;
214  // status==1, 2, 3, 4, 5: tower not expected
215  for (int u = 1; u < (kTriggerTowersAndMem + 1); u++) {
216  if (TowerStatus[u] == 0 || TowerStatus[u] == 9 || TowerStatus[u] == 10) {
218  _expTowersIndex++;
220  }
221  }
222  // resetting counter of expected towers
223  _expTowersIndex = 0;
224 
225  // if number of dccEventBlocks NOT same as expected stop
226  if (!(dccTowerBlocks.size() == _numExpectedTowers)) {
227  // we probably always want to know if this happens
228  edm::LogWarning("EcalTBRawToDigiNumTowerBlocks")
229  << "@SUB=EcalTBDaqFormatter::interpretRawData"
230  << "number of TowerBlocks found (" << dccTowerBlocks.size() << ") differs from expected ("
231  << _numExpectedTowers << ") skipping event";
232 
233  EBDetId idsm(1, 1);
234  dccsizecollection.push_back(idsm);
235 
236  return;
237  }
238 
239  // Access the Tower block
240  for (std::vector<DCCTBTowerBlock*>::iterator itTowerBlock = dccTowerBlocks.begin();
241  itTowerBlock != dccTowerBlocks.end();
242  itTowerBlock++) {
243  tower = (*itTowerBlock)->towerID();
244 
245  // checking if tt in data is the same as tt expected
246  // else skip tower and increment problem counter
247 
248  // compute eta/phi in order to have iTT = _ExpectedTowers[_expTowersIndex]
249  // for the time being consider only zside>0
250 
252 
253  if (!(tower == _ExpectedTowers[_expTowersIndex])) {
254  if (_ExpectedTowers[_expTowersIndex] <= 68) {
255  edm::LogWarning("EcalTBRawToDigiTowerId")
256  << "@SUBS=EcalTBDaqFormatter::interpretRawData"
257  << "TTower id found (=" << tower << ") different from expected (=" << _ExpectedTowers[_expTowersIndex]
258  << ") " << (_expTowersIndex + 1) << "-th tower checked";
259 
260  // report on failed tt_id for regular tower block
261  ttidcollection.push_back(idtt);
262  } else {
263  edm::LogWarning("EcalTBRawToDigiTowerId")
264  << "@SUB=EcalTBDaqFormatter:interpretRawData"
265  << "DecodeMEM: tower " << tower << " is not the same as expected "
266  << ((int)_ExpectedTowers[_expTowersIndex]) << " (according to DCC header channel status)";
267 
268  // report on failed tt_id for mem tower block
269  // chosing channel 1 as representative
270  EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], 1, 1);
271  memttidcollection.push_back(id);
272  }
273 
274  ++_expTowersIndex;
275  continue;
276  } // if TT id found different than expected
277 
278  /*********************************
279  // tt: 1 ... 68: crystal data
280  *********************************/
281  if (0 < (*itTowerBlock)->towerID() && (*itTowerBlock)->towerID() < (kTriggerTowers + 1)) {
282  std::vector<DCCTBXtalBlock*>& xtalDataBlocks = (*itTowerBlock)->xtalBlocks();
283 
284  // if there is no zero suppression, tower block must have have 25 channels in it
285  if ((!dataIsSuppressed) && (xtalDataBlocks.size() != kChannelsPerTower)) {
286  edm::LogWarning("EcalTBRawToDigiTowerSize")
287  << "EcalTBDaqFormatter::interpretRawData, no zero suppression "
288  << "wrong tower block size is: " << xtalDataBlocks.size() << " at LV1 "
289  << (*itEventBlock)->getDataField("LV1") << " for TT " << _ExpectedTowers[_expTowersIndex];
290  // report on wrong tt block size
291  blocksizecollection.push_back(idtt);
292 
293  ++_expTowersIndex;
294  continue;
295  }
296 
297  short cryInTower = 0;
298 
299  short expStripInTower;
300  short expCryInStrip;
301  short expCryInTower = 0;
302 
303  // Access the Xstal data
304  for (std::vector<DCCTBXtalBlock*>::iterator itXtalBlock = xtalDataBlocks.begin();
305  itXtalBlock != xtalDataBlocks.end();
306  itXtalBlock++) { //loop on crys of a tower
307 
308  strip = (*itXtalBlock)->stripID();
309  ch = (*itXtalBlock)->xtalID();
310  cryInTower = (strip - 1) * kChannelsPerCard + (ch - 1);
311 
312  expStripInTower = expCryInTower / 5 + 1;
313  expCryInStrip = expCryInTower % 5 + 1;
314 
315  // FIXME: waiting for geometry to do (TT, strip,chNum) <--> (SMChId)
316  // short abscissa = (_ExpectedTowers[_expTowersIndex]-1) /4;
317  // short ordinate = (_ExpectedTowers[_expTowersIndex]-1) %4;
318  // temporarily choosing central crystal in trigger tower
319  // int cryIdInSM = 45 + ordinate*5 + abscissa * 100;
320 
321  // in case of 0 zuppressed data, check that cryInTower constantly grows
322  if (dataIsSuppressed) {
323  if (strip < 1 || 5 < strip || ch < 1 || 5 < ch) {
324  int sm = 1; // hardcoded because of test beam
325  for (int StripInTower_ = 1; StripInTower_ < 6; StripInTower_++) {
326  for (int CryInStrip_ = 1; CryInStrip_ < 6; CryInStrip_++) {
327  int ic = cryIc(tower, StripInTower_, CryInStrip_);
328  EBDetId idExp(sm, ic, 1);
329  chidcollection.push_back(idExp);
330  }
331  }
332 
333  edm::LogWarning("EcalTBRawToDigiChId")
334  << "EcalTBDaqFormatter::interpretRawData with zero suppression, "
335  << " wrong channel id, since out of range: "
336  << "\t strip: " << strip << "\t channel: " << ch << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
337  << "\t at LV1 : " << (*itEventBlock)->getDataField("LV1");
338 
339  expCryInTower++;
340  continue;
341  }
342 
343  // correct ordering
344  if (cryInTower >= expCryInTower) {
345  expCryInTower = cryInTower + 1;
346  }
347 
348  // cry_id wrong because of incorrect ordering within trigger tower
349  else {
350  edm::LogWarning("EcalTBRawToDigiChId")
351  << "EcalTBDaqFormatter::interpretRawData with zero suppression, "
352  << " based on ch ordering within tt, wrong channel id: "
353  << "\t strip: " << strip << "\t channel: " << ch << "\t cryInTower " << cryInTower
354  << "\t expCryInTower: " << expCryInTower << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
355  << "\t at LV1: " << (*itEventBlock)->getDataField("LV1");
356 
357  int sm = 1; // hardcoded because of test beam
358  for (int StripInTower_ = 1; StripInTower_ < 6; StripInTower_++) {
359  for (int CryInStrip_ = 1; CryInStrip_ < 6; CryInStrip_++) {
360  int ic = cryIc(tower, StripInTower_, CryInStrip_);
361  EBDetId idExp(sm, ic, 1);
362  chidcollection.push_back(idExp);
363  }
364  }
365 
366  // chennel with id which does not follow correct odering
367  expCryInTower++;
368  continue;
369 
370  } // end 'ch_id does not respect growing order'
371 
372  } // end if zero supression
373 
374  else {
375  // checking that ch and strip are within range and cryInTower is as expected
376  if (cryInTower != expCryInTower || strip < 1 || kStripsPerTower < strip || ch < 1 ||
377  kChannelsPerStrip < ch) {
378  int ic = cryIc(tower, expStripInTower, expCryInStrip);
379  int sm = 1; // hardcoded because of test beam
380  EBDetId idExp(sm, ic, 1);
381 
382  edm::LogWarning("EcalTBRawToDigiChId")
383  << "EcalTBDaqFormatter::interpretRawData no zero suppression "
384  << " wrong channel id for channel: " << expCryInStrip << "\t strip: " << expStripInTower
385  << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
386  << "\t at LV1: " << (*itEventBlock)->getDataField("LV1")
387  << "\t (in the data, found channel: " << ch << "\t strip: " << strip << " ).";
388 
389  // report on wrong channel id
390  chidcollection.push_back(idExp);
391 
392  // there has been unexpected crystal id, dataframe not to go to the Event
393  expCryInTower++;
394  continue;
395 
396  } // if channel in data does not equal expected channel
397 
398  expCryInTower++;
399 
400  } // end 'not zero suppression'
401 
402  // data to be stored in EBDataFrame, identified by EBDetId
403  int ic = cryIc(tower, strip, ch);
404  int sm = 1;
405  EBDetId id(sm, ic, 1);
406 
407  // here data frame go into the Event
408  // removed later on (with a pop_back()) if gain==0 or if forbidden-gain-switch
409  digicollection.push_back(id);
410  EBDataFrame theFrame(digicollection.back());
411  std::vector<int> xtalDataSamples = (*itXtalBlock)->xtalDataSamples();
412  //theFrame.setSize(xtalDataSamples.size()); // if needed, to be changed when constructing digicollection
413 
414  // gain cannot be 0, checking for that
415  bool gainIsOk = true;
416  unsigned gain_mask = 12288; //12th and 13th bit
417  std::vector<int> xtalGain;
418 
419  for (unsigned short i = 0; i < xtalDataSamples.size(); ++i) {
420  theFrame.setSample(i, xtalDataSamples[i]);
421 
422  if ((xtalDataSamples[i] & gain_mask) == 0) {
423  gainIsOk = false;
424  }
425 
426  xtalGain.push_back(0);
427  xtalGain[i] |= (xtalDataSamples[i] >> 12);
428  }
429 
430  if (!gainIsOk) {
431  edm::LogWarning("EcalTBRawToDigiGainZero")
432  << "@SUB=EcalTBDaqFormatter::interpretRawData"
433  << " gain==0 for strip: " << expStripInTower << "\t channel: " << expCryInStrip
434  << "\t in TT: " << _ExpectedTowers[_expTowersIndex] << "\t ic: " << ic
435  << "\t at LV1: " << (*itEventBlock)->getDataField("LV1");
436  // report on gain==0
437  gaincollection.push_back(id);
438 
439  // there has been a gain==0, dataframe not to go to the Event
440  digicollection.pop_back();
441  continue; // expCryInTower already incremented
442  }
443 
444  // looking for forbidden gain transitions
445 
446  short firstGainWrong = -1;
447  short numGainWrong = 0;
448 
449  for (unsigned short i = 0; i < xtalGain.size(); i++) {
450  if (i > 0 && xtalGain[i - 1] > xtalGain[i]) {
451  numGainWrong++; // counting forbidden gain transitions
452 
453  if (firstGainWrong == -1) {
454  firstGainWrong = i;
455  edm::LogWarning("EcalTBRawToDigiGainSwitch")
456  << "@SUB=EcalTBDaqFormatter::interpretRawData"
457  << "channelHasGainSwitchProblem: crystal eta = " << id.ieta() << " phi = " << id.iphi();
458  }
459  edm::LogWarning("EcalTBRawToDigiGainSwitch")
460  << "@SUB=EcalTBDaqFormatter::interpretRawData"
461  << "channelHasGainSwitchProblem: sample = " << (i - 1) << " gain: " << xtalGain[i - 1]
462  << " sample: " << i << " gain: " << xtalGain[i];
463  }
464  }
465 
466  if (numGainWrong > 0) {
467  gainswitchcollection.push_back(id);
468 
469  edm::LogWarning("EcalTBRawToDigiGainSwitch") << "@SUB=EcalTBDaqFormatter:interpretRawData"
470  << "channelHasGainSwitchProblem: more than 1 wrong transition";
471 
472  for (unsigned short i1 = 0; i1 < xtalDataSamples.size(); ++i1) {
473  int countADC = 0x00000FFF;
474  countADC &= xtalDataSamples[i1];
475  LogDebug("EcalTBRawToDigi") << "Sample " << i1 << " ADC " << countADC << " Gain " << xtalGain[i1];
476  }
477 
478  // there has been a forbidden gain transition, dataframe not to go to the Event
479  digicollection.pop_back();
480  continue; // expCryInTower already incremented
481 
482  } // END of: 'if there is a forbidden gain transition'
483 
484  } // end loop on crystals within a tower block
485 
486  _expTowersIndex++;
487  } // end: tt1 ... tt68, crystal data
488 
489  /******************************************************************
490  // tt 69 and 70: two mem boxes, holding PN0 ... PN9
491  ******************************************************************/
492  else if ((*itTowerBlock)->towerID() == 69 || (*itTowerBlock)->towerID() == 70) {
493  LogDebug("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::interpretRawData"
494  << "processing mem box num: " << (*itTowerBlock)->towerID();
495 
496  // if tt 69 or 70 found, allocate Pn digi collection
497  if (!pnAllocated) {
498  pndigicollection.reserve(kPns);
499  pnAllocated = true;
500  }
501 
502  DecodeMEM((*itTowerBlock),
503  pndigicollection,
504  memttidcollection,
505  memblocksizecollection,
506  memgaincollection,
507  memchidcollection);
508 
509  } // end of < if it is a mem box>
510 
511  // wrong tt id
512  else {
513  edm::LogWarning("EcalTBRawToDigiTowerId")
514  << "@SUB=EcalTBDaqFormatter::interpretRawData"
515  << " processing tt with ID not existing ( " << (*itTowerBlock)->towerID() << ")";
516  ++_expTowersIndex;
517  continue;
518  } // end: tt id error
519 
520  } // end loop on trigger towers
521 
522  } // end loop on events
523 }
524 
526  EcalPnDiodeDigiCollection& pndigicollection,
527  EcalElectronicsIdCollection& memttidcollection,
528  EcalElectronicsIdCollection& memblocksizecollection,
529  EcalElectronicsIdCollection& memgaincollection,
530  EcalElectronicsIdCollection& memchidcollection) {
531  LogDebug("EcalTBRawToDigi") << "@SUB=EcalTBDaqFormatter::DecodeMEM"
532  << "in mem " << towerblock->towerID();
533 
534  int tower_id = towerblock->towerID();
535  int mem_id = tower_id - 69;
536 
537  // initializing container
538  for (int st_id = 0; st_id < kStripsPerTower; st_id++) {
539  for (int ch_id = 0; ch_id < kChannelsPerStrip; ch_id++) {
540  for (int sa = 0; sa < 11; sa++) {
541  memRawSample_[st_id][ch_id][sa] = -1;
542  }
543  }
544  }
545 
546  // check that tower block id corresponds to mem boxes
547  if (tower_id != 69 && tower_id != 70) {
548  edm::LogWarning("EcalTBRawToDigiTowerId") << "@SUB=EcalTBDaqFormatter:decodeMem"
549  << "DecodeMEM: this is not a mem box tower (" << tower_id << ")";
550  ++_expTowersIndex;
551  return;
552  }
553 
554  /******************************************************************************
555  // getting the raw hits from towerBlock while checking tt and ch data structure
556  ******************************************************************************/
557  std::vector<DCCTBXtalBlock*>& dccXtalBlocks = towerblock->xtalBlocks();
558  std::vector<DCCTBXtalBlock*>::iterator itXtal;
559 
560  // checking mem tower block fo size
561  if (dccXtalBlocks.size() != kChannelsPerTower) {
562  LogDebug("EcalTBRawToDigiDccBlockSize")
563  << "@SUB=EcalTBDaqFormatter:decodeMem"
564  << " wrong dccBlock size, namely: " << dccXtalBlocks.size() << ", for mem " << _ExpectedTowers[_expTowersIndex];
565 
566  // reporting mem-tt block size problem
567  // chosing channel 1 as representative as a dummy...
569  memblocksizecollection.push_back(id);
570 
571  ++_expTowersIndex;
572  return; // if mem tt block size not ok - do not build any Pn digis
573  }
574 
575  // loop on channels of the mem block
576  int cryCounter = 0;
577  int strip_id = 0;
578  int xtal_id = 0;
579 
580  for (itXtal = dccXtalBlocks.begin(); itXtal < dccXtalBlocks.end(); itXtal++) {
581  strip_id = (*itXtal)->getDataField("STRIP ID");
582  xtal_id = (*itXtal)->getDataField("XTAL ID");
583  int wished_strip_id = cryCounter / kStripsPerTower;
584  int wished_ch_id = cryCounter % kStripsPerTower;
585 
586  if ((wished_strip_id + 1) != ((int)strip_id) || (wished_ch_id + 1) != ((int)xtal_id)) {
587  LogDebug("EcalTBRawToDigiChId") << "@SUB=EcalTBDaqFormatter:decodeMem"
588  << " in mem " << towerblock->towerID() << ", expected:\t strip"
589  << (wished_strip_id + 1) << " cry " << (wished_ch_id + 1) << "\tfound: "
590  << " strip " << strip_id << " cry " << xtal_id;
591 
592  // report on crystal with unexpected indices
593  EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], wished_strip_id, wished_ch_id);
594  memchidcollection.push_back(id);
595  }
596 
597  // Accessing the 10 time samples per Xtal:
598  memRawSample_[wished_strip_id][wished_ch_id][1] = (*itXtal)->getDataField("ADC#1");
599  memRawSample_[wished_strip_id][wished_ch_id][2] = (*itXtal)->getDataField("ADC#2");
600  memRawSample_[wished_strip_id][wished_ch_id][3] = (*itXtal)->getDataField("ADC#3");
601  memRawSample_[wished_strip_id][wished_ch_id][4] = (*itXtal)->getDataField("ADC#4");
602  memRawSample_[wished_strip_id][wished_ch_id][5] = (*itXtal)->getDataField("ADC#5");
603  memRawSample_[wished_strip_id][wished_ch_id][6] = (*itXtal)->getDataField("ADC#6");
604  memRawSample_[wished_strip_id][wished_ch_id][7] = (*itXtal)->getDataField("ADC#7");
605  memRawSample_[wished_strip_id][wished_ch_id][8] = (*itXtal)->getDataField("ADC#8");
606  memRawSample_[wished_strip_id][wished_ch_id][9] = (*itXtal)->getDataField("ADC#9");
607  memRawSample_[wished_strip_id][wished_ch_id][10] = (*itXtal)->getDataField("ADC#10");
608 
609  cryCounter++;
610  } // end loop on crystals of mem dccXtalBlock
611 
612  // tower accepted and digi read from all 25 channels.
613  // Increase counter of expected towers before unpacking in the 5 PNs
614  ++_expTowersIndex;
615 
616  /************************************************************
617  // unpacking and 'cooking' the raw numbers to get PN sample
618  ************************************************************/
619  int tempSample = 0;
620  int memStoreIndex = 0;
621  int ipn = 0;
622  for (memStoreIndex = 0; memStoreIndex < 500; memStoreIndex++) {
623  data_MEM[memStoreIndex] = -1;
624  }
625 
626  for (int strip = 0; strip < kStripsPerTower; strip++) { // loop on strips
627  for (int channel = 0; channel < kChannelsPerStrip; channel++) { // loop on channels
628 
629  if (strip % 2 == 0) {
630  ipn = mem_id * 5 + channel;
631  } else {
632  ipn = mem_id * 5 + 4 - channel;
633  }
634 
635  for (int sample = 0; sample < kSamplesPerChannel; sample++) {
636  tempSample = memRawSample_[strip][channel][sample + 1];
637 
638  int new_data = 0;
639  if (strip % 2 == 1) {
640  // 1) if strip number is even, 14 bits are reversed in order
641  for (int ib = 0; ib < 14; ib++) {
642  new_data <<= 1;
643  new_data = new_data | (tempSample & 1);
644  tempSample >>= 1;
645  }
646  } else {
647  new_data = tempSample;
648  }
649 
650  // 2) flip 11th bit for AD9052 still there on MEM !
651  // 3) mask with 1 1111 1111 1111
652  new_data = (new_data ^ 0x800) & 0x3fff; // (new_data XOR 1000 0000 0000) & 11 1111 1111 1111
653  // new_data = (new_data ^ 0x800) & 0x1fff; // (new_data XOR 1000 0000 0000) & 1 1111 1111 1111
654 
655  //(Bit 12) == 1 -> Gain 16; (Bit 12) == 0 -> Gain 1
656  // gain in mem can be 1 or 16 encoded resp. with 0 ir 1 in the 13th bit.
657  // checking and reporting if there is any sample with gain==2,3
658  short sampleGain = (new_data & 0x3000) / 4096;
659  if (sampleGain == 2 || sampleGain == 3) {
661  memgaincollection.push_back(id);
662 
663  edm::LogWarning("EcalTBRawToDigiGainZero")
664  << "@SUB=EcalTBDaqFormatter:decodeMem"
665  << "in mem " << towerblock->towerID() << " :\t strip: " << (strip + 1) << " cry: " << (channel + 1)
666  << " has 14th bit non zero! Gain results: " << sampleGain << ".";
667 
668  continue;
669  } // end 'if gain is zero'
670 
671  memStoreIndex = ipn * 50 + strip * kSamplesPerChannel + sample;
672  // storing in data_MEM also the gain bits
673  data_MEM[memStoreIndex] = new_data & 0x3fff;
674 
675  } // loop on samples
676  } // loop on strips
677  } // loop on channels
678 
679  for (int pnId = 0; pnId < kPnPerTowerBlock; pnId++)
680  pnIsOkInBlock[pnId] = true;
681  // if anything was wrong with mem_tt_id or mem_tt_size: you would have already exited
682  // otherwise, if any problem with ch_gain or ch_id: must not produce digis for the pertaining Pn
683 
684  if (!(memgaincollection.empty() && memchidcollection.empty())) {
685  for (EcalElectronicsIdCollection::const_iterator idItr = memgaincollection.begin();
686  idItr != memgaincollection.end();
687  ++idItr) {
688  int ch = (*idItr).channelId();
689  ch = (ch - 1) / 5;
690  pnIsOkInBlock[ch] = false;
691  }
692 
693  for (EcalElectronicsIdCollection::const_iterator idItr = memchidcollection.begin();
694  idItr != memchidcollection.end();
695  ++idItr) {
696  int ch = (*idItr).channelId();
697  ch = (ch - 1) / 5;
698  pnIsOkInBlock[ch] = false;
699  }
700 
701  } // end: if any ch_gain or ch_id problems exclude the Pn's from digi production
702 
703  // looping on PN's of current mem box
704  for (int pnId = 1; pnId < (kPnPerTowerBlock + 1); pnId++) {
705  // if present Pn has any of its 5 channels with problems, do not produce digi for it
706  if (!pnIsOkInBlock[pnId - 1])
707  continue;
708 
709  // DccId set to 28 to be consistent with ism==1
710  EcalPnDiodeDetId PnId(1, 28, pnId + kPnPerTowerBlock * mem_id);
711  EcalPnDiodeDigi thePnDigi(PnId);
712 
713  thePnDigi.setSize(kSamplesPerPn);
714 
715  for (int sample = 0; sample < kSamplesPerPn; sample++) {
716  EcalFEMSample thePnSample(data_MEM[(mem_id)*250 + (pnId - 1) * kSamplesPerPn + sample]);
717  thePnDigi.setSample(sample, thePnSample);
718  }
719  pndigicollection.push_back(thePnDigi);
720  }
721 }
722 
723 std::pair<int, int> EcalTBDaqFormatter::cellIndex(int tower_id, int strip, int ch) {
724  int xtal = (strip - 1) * 5 + ch - 1;
725  // std::cout << " cellIndex input xtal " << xtal << std::endl;
726  std::pair<int, int> ind;
727 
728  int eta = (tower_id - 1) / kTowersInPhi * kCardsPerTower;
729  int phi = (tower_id - 1) % kTowersInPhi * kChannelsPerCard;
730 
731  if (rightTower(tower_id))
732  eta += xtal / kCardsPerTower;
733  else
734  eta += (kCrystalsPerTower - 1 - xtal) / kCardsPerTower;
735 
736  if ((rightTower(tower_id) && (xtal / kCardsPerTower) % 2 == 1) ||
737  (!rightTower(tower_id) && (xtal / kCardsPerTower) % 2 == 0))
738 
739  phi += (kChannelsPerCard - 1 - xtal % kChannelsPerCard);
740  else
741  phi += xtal % kChannelsPerCard;
742 
743  ind.first = eta + 1;
744  ind.second = phi + 1;
745 
746  // std::cout << " EcalTBDaqFormatter::cell_index eta " << ind.first << " phi " << ind.second << " " << std::endl;
747 
748  return ind;
749 }
750 
751 int EcalTBDaqFormatter::cryIc(int tower, int strip, int ch) {
752  if (strip < 1 || 5 < strip || ch < 1 || 5 < ch || 68 < tower) {
753  edm::LogWarning("EcalTBRawToDigiChId") << "EcalTBDaqFormatter::interpretRawData (cryIc) "
754  << " wrong channel id, since out of range: "
755  << "\t strip: " << strip << "\t channel: " << ch << "\t in TT: " << tower;
756  return -1;
757  }
758 
759  std::pair<int, int> cellInd = EcalTBDaqFormatter::cellIndex(tower, strip, ch);
760  return cellInd.second + (cellInd.first - 1) * kCrystalsInPhi;
761 }
762 
764  if ((tower > 12 && tower < 21) || (tower > 28 && tower < 37) || (tower > 44 && tower < 53) ||
765  (tower > 60 && tower < 69))
766  return true;
767  else
768  return false;
769 }
770 
771 bool EcalTBDaqFormatter::leftTower(int tower) const { return !rightTower(tower); }
void push_back(const Digi &digi)
bool Decode(unsigned long headerWord, EcalDCCHeaderBlock *theHeader)
bool rightTower(int tower) const
int ib
Definition: cuy.py:661
void setSelectiveReadout(const bool &selectiveReadout)
std::vector< DCCTBXtalBlock * > & xtalBlocks()
Definition: DCCTowerBlock.h:48
uint16_t *__restrict__ id
void setFedId(const int &fedId)
DCCTBDataParser * theParser_
const_iterator end() const
Definition: EDCollection.h:122
Ecal readout channel identification [32:20] Unused (so far) [19:13] DCC id [12:6] tower [5:3] strip [...
void setBasicTriggerType(const short &triggerType)
void setSize(int size)
int cryIc(int tower_id, int strip, int xtal)
void interpretRawData(const FEDRawData &data, EBDigiCollection &digicollection, EcalPnDiodeDigiCollection &pndigicollection, EcalRawDataCollection &DCCheaderCollection, EBDetIdCollection &dccsizecollection, EcalElectronicsIdCollection &ttidcollection, EcalElectronicsIdCollection &blocksizecollection, EBDetIdCollection &chidcollection, EBDetIdCollection &gaincollection, EBDetIdCollection &gainswitchcollection, EcalElectronicsIdCollection &memttidcollection, EcalElectronicsIdCollection &memblocksizecollection, EcalElectronicsIdCollection &memgaincollection, EcalElectronicsIdCollection &memchidcollection, EcalTrigPrimDigiCollection &tpcollection)
void push_back(T const &t)
void push_back(T const &t)
Definition: EDCollection.h:60
std::vector< DCCTBEventBlock * > & dccEvents()
void DecodeMEM(DCCTBTowerBlock *towerblock, EcalPnDiodeDigiCollection &pndigicollection, EcalElectronicsIdCollection &memttidcollection, EcalElectronicsIdCollection &memblocksizecollection, EcalElectronicsIdCollection &memgaincollection, EcalElectronicsIdCollection &memchidcollection)
bool leftTower(int tower) const
void setFEStatus(const std::vector< short > &feStatus)
void setRunNumber(const int &run)
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
U second(std::pair< T, U > const &p)
void setZeroSuppression(const bool &zeroSuppression)
bool empty() const
Definition: EDCollection.h:77
std::pair< int, int > cellIndex(int tower_id, int strip, int xtal)
bool pnIsOkInBlock[kPnPerTowerBlock]
void setSample(int i, const EcalTriggerPrimitiveSample &sam)
void setTestZeroSuppression(const bool &testZeroSuppression)
void setTccStatus(const std::vector< short > &tccStatus)
void reserve(size_t isize)
unsigned _ExpectedTowers[71]
const_iterator begin() const
Definition: EDCollection.h:117
void setErrors(const int &dccErrors)
void setSrpStatus(const short &srpStatus)
void setOrbit(const int &orbit)
void setSample(int i, EcalMGPASample sam)
Definition: EcalDataFrame.h:43
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
int memRawSample_[kStripsPerTower][kChannelsPerStrip][kSamplesPerChannel+1]
#define MAX_TCC_SIZE
void reserve(size_type n)
void setId(const int &dccId)
void setLV1(const int &LV1)
void setBX(const int &BX)
void setSample(int i, const EcalFEMSample &sam)
Log< level::Warning, false > LogWarning
void parseBuffer(const uint32_t *buffer, uint32_t bufferSize, bool singleEvent=false)
#define MAX_TT_SIZE
#define LogDebug(id)
std::vector< T >::const_iterator const_iterator
Definition: EDCollection.h:19