CMS 3D CMS Logo

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