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