CMS 3D CMS Logo

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