CMS 3D CMS Logo

TowerBlockFormatter.cc
Go to the documentation of this file.
1 #include <memory>
2 #include <list>
3 
5 
9 
10 using namespace std;
11 
13 
15  FEDRawData& rawdata,
16  const EcalElectronicsMapping* TheMapping)
17 
18 {
19  int bx = bx_;
20  int lv1 = lv1_ - 1;
21 
22  int rdsize = rawdata.size() / 8; // size in Word64
23 
24  const EBDetId& ebdetid = dataframe.id();
25 
26  int DCCid = TheMapping->DCCid(ebdetid);
27  int FEDid = FEDNumbering::MINECALFEDID + DCCid;
28 
29  int nsamples = dataframe.size();
30  // -- FE number
31  const EcalElectronicsId& elid = TheMapping->getElectronicsId(ebdetid);
32  int iFE = elid.towerId();
33  if (iFE <= 0 || iFE > 68)
34  throw cms::Exception("InvalidFEid") << "TowerBlockFormatter::DigiToRaw : Invalid iFE " << iFE << endl;
35 
36  map<int, map<int, int> >::iterator fen = FEDorder.find(FEDid);
37  map<int, map<int, int> >::iterator fed = FEDmap.find(FEDid);
38 
39  if (fen == FEDorder.end()) {
40  if (debug_)
41  cout << "New FED in TowerBlockFormatter " << dec << FEDid << " 0x" << hex << FEDid << endl;
42  map<int, int> FEorder;
43  pair<map<int, map<int, int> >::iterator, bool> t1 =
44  FEDorder.insert(map<int, map<int, int> >::value_type(FEDid, FEorder));
45  map<int, int> FEmap;
46  pair<map<int, map<int, int> >::iterator, bool> t2 =
47  FEDmap.insert(map<int, map<int, int> >::value_type(FEDid, FEmap));
48  fen = t1.first;
49  fed = t2.first;
50  }
51 
52  map<int, int>& FEorder = (*fen).second;
53  map<int, int>& FEmap = (*fed).second;
54 
55  map<int, int>::iterator fe = FEorder.find(iFE);
56  int FE_order;
57  int FE_index;
58  if (fe != FEorder.end()) {
59  FE_order = (*fe).second;
60  map<int, int>::iterator ff = FEmap.find(FE_order);
61  if (ff == FEmap.end())
62  cout << "Error with maps... " << endl;
63  FE_index = (*ff).second;
64  if (debug_)
65  cout << "FE already there, FE_index = " << dec << FE_index << " FEorder " << FE_order << endl;
66  } else {
67  if (debug_)
68  cout << "New FE in TowerBlockFormatter FE " << dec << iFE << " 0x" << hex << iFE << " in FED id " << dec << FEDid
69  << endl;
70  int inser = rdsize;
71  int number_FEs = FEorder.size() - 1;
72  FE_order = number_FEs + 1;
73  pair<map<int, int>::iterator, bool> t2 = FEorder.insert(map<int, int>::value_type(iFE, FE_order));
74  if (!t2.second)
75  cout << " FE insertion failed...";
76  pair<map<int, int>::iterator, bool> tt = FEmap.insert(map<int, int>::value_type(FE_order, inser));
77  fe = tt.first;
78  FE_index = (*fe).second;
79  if (debug_)
80  cout << "Build the Tower Block header for FE id " << iFE << " start at line " << rdsize << endl;
81  if (debug_)
82  cout << "This is the Fe number (order) " << number_FEs + 1 << endl;
83  rawdata.resize(8 * rdsize + 8);
84  unsigned char* pData = rawdata.data();
85  pData[8 * FE_index] = iFE & 0xFF;
86  pData[8 * FE_index + 1] = (nsamples & 0x7F);
87  pData[8 * FE_index + 2] = bx & 0xFF;
88  pData[8 * FE_index + 3] = (bx >> 8) & 0x0F;
89  pData[8 * FE_index + 3] |= 0xa0;
90  pData[8 * FE_index + 4] = lv1 & 0xFF;
91  pData[8 * FE_index + 5] = (lv1 >> 8) & 0x0F;
92  pData[8 * FE_index + 6] = 1;
93  pData[8 * FE_index + 7] = 0xc0;
94  if (debug_)
95  print(rawdata);
96  }
97 
98  // -- Crystal number inside the SM :
99 
100  int istrip = elid.stripId();
101  int ichannel = elid.xtalId();
102 
103  if (debug_)
104  cout << "Now add crystal : strip channel " << dec << istrip << " " << ichannel << endl;
105 
106  unsigned char* pData = rawdata.data();
107 
108  vector<unsigned char> vv(&pData[0], &pData[rawdata.size()]);
109 
110  int n_add = 2 + 2 * nsamples; // 2 bytes per sample, plus 2 bytes before sample 0
111  if (n_add % 8 != 0)
112  n_add = n_add / 8 + 1;
113  else
114  n_add = n_add / 8;
115  if (debug_)
116  cout << "will add " << n_add << " lines of 64 bits at line " << (FE_index + 1) << endl;
117  rawdata.resize(rawdata.size() + 8 * n_add);
118  unsigned char* ppData = rawdata.data();
119 
120  vector<unsigned char>::iterator iter = vv.begin() + 8 * (FE_index + 1);
121 
122  vector<unsigned char> toadd(n_add * 8);
123 
124  int tzs = 0;
125  toadd[0] = (istrip & 0x7) + ((ichannel & 0x7) << 4);
126  toadd[1] = (tzs & 0x1) << 12;
127 
128  for (int isample = 0; isample < (n_add * 8 - 2) / 2; isample++) {
129  if (isample < nsamples) {
130  uint16_t word = (dataframe.sample(isample)).raw(); // 16 bits word corresponding to this sample
131  toadd[2 + isample * 2] = word & 0x00FF;
132  toadd[2 + isample * 2 + 1] = (word & 0xFF00) >> 8;
133  } else {
134  toadd[2 + isample * 2] = 0;
135  toadd[2 + isample * 2 + 1] = 0;
136  }
137  if (isample % 2 == 0)
138  toadd[2 + isample * 2 + 1] |= 0xc0; // need to add the B11 header...
139  }
140 
141  vv.insert(iter, toadd.begin(), toadd.end());
142 
143  // update the pData for this FED :
144  for (int i = 0; i < (int)vv.size(); i++) {
145  ppData[i] = vv[i];
146  }
147 
148  if (debug_) {
149  cout << "pData for this FED is now " << endl;
150  print(rawdata);
151  }
152 
153  // and update the FEmap for this FED :
154  for (int i = FE_order + 1; i < (int)FEorder.size(); i++) {
155  FEmap[i] += n_add;
156  if (debug_)
157  cout << "FEmap updated for fe number " << dec << i << endl;
158  if (debug_)
159  cout << " FEmap[" << i << "] = " << FEmap[i] << endl;
160  }
161 
162  // update the block length
163  int blocklength = ppData[8 * FE_index + 6] + ((ppData[8 * FE_index + 7] & 0x1) << 8);
164  blocklength += n_add;
165  ppData[8 * FE_index + 6] = blocklength & 0xFF;
166  ppData[8 * FE_index + 7] |= (blocklength & 0x100) >> 8;
167 }
168 
170  // -- Need to reorder the FE's in teh TowerBlock. They come in the right
171  // order when reading the unsuppressed digis, but ganz durcheinander
172  // when reading the SelectiveReadout_Suppressed digis.
173 
174  if (debug_)
175  cout << "enter in TowerBlockFormatter::EndEvent. First reorder the FE's. " << endl;
176 
177  for (int idcc = 1; idcc <= 54; idcc++) {
178  // debug_ = (idcc == 34);
179 
180  //if (idcc != 34) continue;
181 
182  int FEDid = FEDNumbering::MINECALFEDID + idcc;
183  // cout << "Process FED " << FEDid << endl;
184  FEDRawData& fedData = productRawData->FEDData(FEDid);
185  if (fedData.size() <= 16)
186  continue;
187 
188  if (debug_)
189  cout << "This is FEDid = " << FEDid << endl;
190 
191  unsigned char* pData = fedData.data();
192  // Word64* words = reinterpret_cast<Word64*>(const_cast<unsigned char*>(pData));
193  Word64* words = reinterpret_cast<Word64*>(pData);
194 
195  int length = fedData.size() / 8;
196  int iDAQ_header(-1), iDCC_header(-1), iTCCBlock_header(-1), iSRBlock_header(-1), iTowerBlock_header(-1),
197  iDAQ_trailer(-1);
198 
199  for (int i = length - 1; i > -1; i--) {
200  if (((words[i] >> 60) & 0xF) == 0x5)
201  iDAQ_header = i;
202  if (((words[i] >> 62) & 0x3) == 0x0)
203  iDCC_header = i;
204  if (((words[i] >> 61) & 0x7) == 0x3)
205  iTCCBlock_header = i;
206  if (((words[i] >> 61) & 0x7) == 0x4)
207  iSRBlock_header = i;
208  if (((words[i] >> 62) & 0x3) == 0x3)
209  iTowerBlock_header = i;
210  if (((words[i] >> 60) & 0xF) == 0xA)
211  iDAQ_trailer = i;
212  }
213 
214  if (iTowerBlock_header < 0)
215  iTowerBlock_header = iDAQ_trailer;
216  if (iSRBlock_header < 0)
217  iSRBlock_header = iTowerBlock_header;
218  if (iTCCBlock_header < 0)
219  iTCCBlock_header = iSRBlock_header;
220 
221  if (debug_) {
222  cout << "iDAQ_header = " << iDAQ_header << endl;
223  cout << " iDCC_header = " << iDCC_header << endl;
224  cout << " iTCCBlock_header = " << iTCCBlock_header << endl;
225  cout << " iSRBlock_header = " << iSRBlock_header << endl;
226  cout << " iTowerBlock_header = " << iTowerBlock_header << endl;
227  cout << " iDAQ_trailer = " << iDAQ_trailer << endl;
228  }
229 
230  std::map<int, int> FrontEnd;
231  std::map<int, std::vector<Word64> > Map_xtal_data;
232 
233  int iTowerBlock_header_keep = iTowerBlock_header;
234 
235  while (iTowerBlock_header < iDAQ_trailer) {
236  int fe = words[iTowerBlock_header] & 0xFF;
237  int nlines = (words[iTowerBlock_header] >> 48) & 0x1FF;
238  if (debug_)
239  cout << "This is FE number " << fe << "needs nlines = " << nlines << endl;
240  FrontEnd[fe] = nlines;
241  std::vector<Word64> xtal_data;
242  for (int j = 0; j < nlines; j++) {
243  Word64 ww = words[iTowerBlock_header + j];
244  xtal_data.push_back(ww);
245  }
246  Map_xtal_data[fe] = xtal_data;
247  iTowerBlock_header += nlines;
248  }
249 
250  if (debug_) {
251  cout << "vector of FrontEnd : " << FrontEnd.size() << endl;
252  for (std::map<int, int>::const_iterator it = FrontEnd.begin(); it != FrontEnd.end(); it++) {
253  int fe = it->first;
254  int l = it->second;
255  cout << "FE line " << fe << " " << l << endl;
256  }
257  }
258 
259  iTowerBlock_header = iTowerBlock_header_keep;
260  for (std::map<int, int>::const_iterator it = FrontEnd.begin(); it != FrontEnd.end(); it++) {
261  int fe = it->first;
262  int nlines = it->second;
263  if (debug_)
264  cout << "iTowerBlock_header = " << iTowerBlock_header << endl;
265  vector<Word64> xtal_data = Map_xtal_data[fe];
266  for (int j = 0; j < nlines; j++) {
267  words[iTowerBlock_header + j] = xtal_data[j];
268  if (debug_)
269  cout << "update line " << iTowerBlock_header + j << endl;
270  }
271  if (debug_) {
272  int jFE = pData[8 * (iTowerBlock_header)];
273  cout << "Front End on RD : " << jFE << endl;
274  }
275  iTowerBlock_header += nlines;
276  }
277 
278  // -- now the FEs are ordered. STill need to order the xtals within FEs;
279  // need : xtal 1,2,3,4, 5 in strip 1, xtal 1,2,3,4,5 in strip 2 etc..
280  // with possibly missing ones.
281 
282  if (debug_)
283  cout << "now reorder the xtals within the FEs" << endl;
284 
285  iTowerBlock_header = iTowerBlock_header_keep;
286 
287  for (std::map<int, int>::const_iterator it = FrontEnd.begin(); it != FrontEnd.end(); it++) {
288  int fe = it->first;
289  if (fe > 68)
290  cout << "Problem... fe = " << fe << " in FEDid = " << FEDid << endl;
291  if (debug_)
292  cout << " This is for FE = " << fe << endl;
293  int nlines = it->second;
294  int timesamples = pData[8 * iTowerBlock_header + 1] & 0x7F;
295  int n4 = timesamples - 3;
296  int n_lines4 = n4 / 4;
297  if (n4 % 4 != 0)
298  n_lines4++;
299  if (n_lines4 < 0)
300  n_lines4 = 0;
301  int Nxtal_max = (nlines - 1) / (1 + n_lines4);
302  int Nxtal = 0;
303 
304  map<int, map<int, vector<Word64> > > Strip_Map;
305 
306  while (Nxtal < Nxtal_max) {
307  int i_xtal = iTowerBlock_header + 1 + Nxtal * (1 + n_lines4);
308  int strip = words[i_xtal] & 0x7;
309  int xtal = (words[i_xtal] >> 4) & 0x7;
310 
311  map<int, map<int, vector<Word64> > >::iterator iit = Strip_Map.find(strip);
312 
313  map<int, vector<Word64> > NewMap;
314  map<int, vector<Word64> > Xtal_Map;
315 
316  if (iit == Strip_Map.end()) { // new strip
317  Xtal_Map = NewMap;
318  } else {
319  Xtal_Map = iit->second;
320  }
321 
322  std::vector<Word64> xtal_data;
323  for (int j = 0; j < n_lines4 + 1; j++) {
324  Word64 ww = words[i_xtal + j];
325  xtal_data.push_back(ww);
326  }
327  Xtal_Map[xtal] = xtal_data;
328  Strip_Map[strip] = Xtal_Map;
329 
330  Nxtal++;
331  }
332 
333  // now, update the xtals for this FE :
334 
335  int idx = 0;
336  for (map<int, map<int, vector<Word64> > >::const_iterator jt = Strip_Map.begin(); jt != Strip_Map.end(); jt++) {
337  int strip = jt->first;
338  if (debug_)
339  cout << " this is strip number " << strip << endl;
340  map<int, vector<Word64> > Xtal_Map = jt->second;
341 
342  for (map<int, vector<Word64> >::const_iterator kt = Xtal_Map.begin(); kt != Xtal_Map.end(); kt++) {
343  int xtal = kt->first;
344  if (debug_)
345  cout << " this is xtal number " << xtal << endl;
346  vector<Word64> xtal_data = kt->second;
347 
348  int mlines = (int)xtal_data.size();
349  if (debug_)
350  cout << " mlines = " << mlines << endl;
351  for (int j = 0; j < mlines; j++) {
352  int line = iTowerBlock_header + 1 + idx + j;
353  if (line >= iDAQ_trailer)
354  cout << "smth wrong... line " << line << " trailer " << iDAQ_trailer << endl;
355  words[line] = xtal_data[j];
356  if (debug_)
357  cout << " updated line " << iTowerBlock_header + idx + j << endl;
358  }
359  idx += mlines;
360 
361  } // end loop on xtals
362  Xtal_Map.clear();
363 
364  } // end loop on strips
365 
366  Strip_Map.clear();
367 
368  iTowerBlock_header += nlines;
369  } // end loop on FEs
370 
371  if (debug_)
372  cout << " DONE FOR FED " << FEDid << endl;
373  FrontEnd.clear();
374  Map_xtal_data.clear();
375 
376  } // end loop on DCC
377 
378  // cout << " finished reorder, now clean up " << endl;
379 
380  // -- clean up
381 
382  // FEDmap.empty();
383  // FEDorder.empty();
384 
385  // cout << "end of EndEvent " << endl;
386 }
387 
389  FEDRawData& rawdata,
390  const EcalElectronicsMapping* TheMapping)
391 
392 // -- now that we have the EcalElectronicsMapping, this method could probably be
393 // merged with DigiToRaw(EBdataframe).
394 // Keep as it is for the while...
395 {
396  // debug_ = false;
397 
398  int bx = bx_;
399  int lv1 = lv1_;
400 
401  int rdsize = rawdata.size() / 8; // size in Word64
402 
403  const EEDetId& eedetid = dataframe.id();
404  EcalElectronicsId elid = TheMapping->getElectronicsId(eedetid);
405  int DCCid = elid.dccId();
406  int FEDid = FEDNumbering::MINECALFEDID + DCCid;
407  int iFE = elid.towerId();
408 
409  if (debug_)
410  cout << "enter in TowerBlockFormatter::DigiToRaw DCCid FEDid iFE " << dec << DCCid << " " << FEDid << " " << iFE
411  << endl;
412 
413  int nsamples = dataframe.size();
414 
415  if (iFE <= 0 || iFE > 68) {
416  cout << "invalid iFE for EndCap DCCid iFE " << DCCid << " " << iFE << endl;
417  return;
418  }
419 
420  map<int, map<int, int> >::iterator fen = FEDorder.find(FEDid);
421  map<int, map<int, int> >::iterator fed = FEDmap.find(FEDid);
422 
423  if (fen == FEDorder.end()) {
424  if (debug_)
425  cout << "New FED in TowerBlockFormatter " << dec << FEDid << " 0x" << hex << FEDid << endl;
426  map<int, int> FEorder;
427  pair<map<int, map<int, int> >::iterator, bool> t1 =
428  FEDorder.insert(map<int, map<int, int> >::value_type(FEDid, FEorder));
429  map<int, int> FEmap;
430  pair<map<int, map<int, int> >::iterator, bool> t2 =
431  FEDmap.insert(map<int, map<int, int> >::value_type(FEDid, FEmap));
432  fen = t1.first;
433  fed = t2.first;
434  }
435 
436  map<int, int>& FEorder = (*fen).second;
437  map<int, int>& FEmap = (*fed).second;
438 
439  map<int, int>::iterator fe = FEorder.find(iFE);
440  int FE_order;
441  int FE_index;
442  if (fe != FEorder.end()) {
443  FE_order = (*fe).second;
444  map<int, int>::iterator ff = FEmap.find(FE_order);
445  if (ff == FEmap.end())
446  cout << "Error with maps... " << endl;
447  FE_index = (*ff).second;
448  if (debug_)
449  cout << "FE already there, FE_index = " << dec << FE_index << " FEorder " << FE_order << endl;
450  } else {
451  if (debug_)
452  cout << "New FE in TowerBlockFormatter FE " << dec << iFE << " 0x" << hex << iFE << " in FED id " << dec << FEDid
453  << endl;
454  int inser = rdsize;
455  int number_FEs = FEorder.size() - 1;
456  FE_order = number_FEs + 1;
457  pair<map<int, int>::iterator, bool> t2 = FEorder.insert(map<int, int>::value_type(iFE, FE_order));
458  if (!t2.second)
459  cout << " FE insertion failed...";
460  pair<map<int, int>::iterator, bool> tt = FEmap.insert(map<int, int>::value_type(FE_order, inser));
461  fe = tt.first;
462  FE_index = (*fe).second;
463  if (debug_)
464  cout << "Build the Tower Block header for FE id " << iFE << " start at line " << rdsize << endl;
465  if (debug_)
466  cout << "This is the Fe number (order) " << number_FEs + 1 << endl;
467  rawdata.resize(8 * rdsize + 8);
468  unsigned char* pData = rawdata.data();
469 
470  pData[8 * FE_index] = iFE & 0xFF;
471  pData[8 * FE_index + 1] = (nsamples & 0x7F);
472  pData[8 * FE_index + 2] = bx & 0xFF;
473  pData[8 * FE_index + 3] = (bx >> 8) & 0x0F;
474  pData[8 * FE_index + 3] |= 0xa0;
475  pData[8 * FE_index + 4] = lv1 & 0xFF;
476  pData[8 * FE_index + 5] = (lv1 >> 8) & 0x0F;
477  pData[8 * FE_index + 6] = 1;
478  pData[8 * FE_index + 7] = 0xc0;
479  if (debug_)
480  print(rawdata);
481  }
482 
483  // -- Crystal number inside the SM :
484  int istrip = elid.stripId();
485  int ichannel = elid.xtalId();
486 
487  if (debug_)
488  cout << "Now add crystal strip channel " << dec << istrip << " " << ichannel << endl;
489 
490  unsigned char* pData = rawdata.data();
491 
492  vector<unsigned char> vv(&pData[0], &pData[rawdata.size()]);
493 
494  int n_add = 2 + 2 * nsamples; // 2 bytes per sample, plus 2 bytes before sample 0
495  if (n_add % 8 != 0)
496  n_add = n_add / 8 + 1;
497  else
498  n_add = n_add / 8;
499  if (debug_)
500  cout << "nsamples = " << dec << nsamples << endl;
501  if (debug_)
502  cout << "will add " << n_add << " lines of 64 bits at line " << (FE_index + 1) << endl;
503  rawdata.resize(rawdata.size() + 8 * n_add);
504  unsigned char* ppData = rawdata.data();
505 
506  vector<unsigned char>::iterator iter = vv.begin() + 8 * (FE_index + 1);
507 
508  vector<unsigned char> toadd(n_add * 8);
509 
510  int tzs = 0;
511  toadd[0] = (istrip & 0x7) + ((ichannel & 0x7) << 4);
512  toadd[1] = (tzs & 0x1) << 12;
513 
514  for (int isample = 0; isample < (n_add * 8 - 2) / 2; isample++) {
515  if (isample < nsamples) {
516  uint16_t word = (dataframe.sample(isample)).raw(); // 16 bits word corresponding to this sample
517  toadd[2 + isample * 2] = word & 0x00FF;
518  toadd[2 + isample * 2 + 1] = (word & 0xFF00) >> 8;
519  } else {
520  toadd[2 + isample * 2] = 0;
521  toadd[2 + isample * 2 + 1] = 0;
522  }
523  if (isample % 2 == 0)
524  toadd[2 + isample * 2 + 1] |= 0xc0; // need to add the B11 header...
525  }
526 
527  vv.insert(iter, toadd.begin(), toadd.end());
528 
529  // update the pData for this FED :
530  for (int i = 0; i < (int)vv.size(); i++) {
531  ppData[i] = vv[i];
532  }
533 
534  if (debug_) {
535  cout << "pData for this FED is now " << endl;
536  print(rawdata);
537  }
538 
539  // and update the FEmap for this FED :
540  for (int i = FE_order + 1; i < (int)FEorder.size(); i++) {
541  FEmap[i] += n_add;
542  if (debug_)
543  cout << "FEmap updated for fe number " << dec << i << endl;
544  if (debug_)
545  cout << " FEmap[" << i << "] = " << FEmap[i] << endl;
546  }
547 
548  // update the block length
549  int blocklength = ppData[8 * FE_index + 6] + ((ppData[8 * FE_index + 7] & 0x1) << 8);
550  blocklength += n_add;
551  ppData[8 * FE_index + 6] = blocklength & 0xFF;
552  ppData[8 * FE_index + 7] |= (blocklength & 0x100) >> 8;
553 }
std::map< int, std::map< int, int > > FEDmap
Ecal readout channel identification [32:20] Unused (so far) [19:13] DCC id [12:6] tower [5:3] strip [...
int DCCid(const EBDetId &id) const
returns the DCC of an EBDetId
int dccId() const
get the DCC (Ecal Local DCC value not global one) id
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
key_type id() const
Definition: EBDataFrame.h:28
key_type id() const
Definition: EEDataFrame.h:24
void print(FEDRawData &rawdata)
int size() const
Definition: EcalDataFrame.h:26
uint64_t word
Definition: TTTypes.h:54
void resize(size_t newsize)
Definition: FEDRawData.cc:28
int towerId() const
get the tower id
const bool debug_
EcalMGPASample sample(int i) const
Definition: EcalDataFrame.h:29
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
int stripId() const
get the tower id
int xtalId() const
get the channel id
EcalElectronicsId getElectronicsId(const DetId &id) const
Get the electronics id for this det id.
Definition: Config.py:1
TowerBlockFormatter(BlockFormatter::Config const &, BlockFormatter::Params const &)
void EndEvent(FEDRawDataCollection *productRawData)
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
void DigiToRaw(const EBDataFrame &dataframe, FEDRawData &rawdata, const EcalElectronicsMapping *TheMapping)
std::map< int, std::map< int, int > > FEDorder