File indexing completed on 2023-03-17 10:59:37
0001 #include <memory>
0002 #include <list>
0003
0004 #include "EventFilter/EcalDigiToRaw/interface/TowerBlockFormatter.h"
0005
0006 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0007 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
0008 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0009
0010 using namespace std;
0011
0012 TowerBlockFormatter::TowerBlockFormatter(Config const& iC, Params const& iP) : BlockFormatter(iC, iP) {}
0013
0014 void TowerBlockFormatter::DigiToRaw(const EBDataFrame& dataframe,
0015 FEDRawData& rawdata,
0016 const EcalElectronicsMapping* TheMapping)
0017
0018 {
0019 int bx = bx_;
0020 int lv1 = lv1_ - 1;
0021
0022 int rdsize = rawdata.size() / 8;
0023
0024 const EBDetId& ebdetid = dataframe.id();
0025
0026 int DCCid = TheMapping->DCCid(ebdetid);
0027 int FEDid = FEDNumbering::MINECALFEDID + DCCid;
0028
0029 int nsamples = dataframe.size();
0030
0031 const EcalElectronicsId& elid = TheMapping->getElectronicsId(ebdetid);
0032 int iFE = elid.towerId();
0033 if (iFE <= 0 || iFE > 68)
0034 throw cms::Exception("InvalidFEid") << "TowerBlockFormatter::DigiToRaw : Invalid iFE " << iFE << endl;
0035
0036 map<int, map<int, int> >::iterator fen = FEDorder.find(FEDid);
0037 map<int, map<int, int> >::iterator fed = FEDmap.find(FEDid);
0038
0039 if (fen == FEDorder.end()) {
0040 if (debug_)
0041 cout << "New FED in TowerBlockFormatter " << dec << FEDid << " 0x" << hex << FEDid << endl;
0042 map<int, int> FEorder;
0043 pair<map<int, map<int, int> >::iterator, bool> t1 =
0044 FEDorder.insert(map<int, map<int, int> >::value_type(FEDid, FEorder));
0045 map<int, int> FEmap;
0046 pair<map<int, map<int, int> >::iterator, bool> t2 =
0047 FEDmap.insert(map<int, map<int, int> >::value_type(FEDid, FEmap));
0048 fen = t1.first;
0049 fed = t2.first;
0050 }
0051
0052 map<int, int>& FEorder = (*fen).second;
0053 map<int, int>& FEmap = (*fed).second;
0054
0055 map<int, int>::iterator fe = FEorder.find(iFE);
0056 int FE_order;
0057 int FE_index;
0058 if (fe != FEorder.end()) {
0059 FE_order = (*fe).second;
0060 map<int, int>::iterator ff = FEmap.find(FE_order);
0061 if (ff == FEmap.end())
0062 cout << "Error with maps... " << endl;
0063 FE_index = (*ff).second;
0064 if (debug_)
0065 cout << "FE already there, FE_index = " << dec << FE_index << " FEorder " << FE_order << endl;
0066 } else {
0067 if (debug_)
0068 cout << "New FE in TowerBlockFormatter FE " << dec << iFE << " 0x" << hex << iFE << " in FED id " << dec << FEDid
0069 << endl;
0070 int inser = rdsize;
0071 int number_FEs = FEorder.size() - 1;
0072 FE_order = number_FEs + 1;
0073 pair<map<int, int>::iterator, bool> t2 = FEorder.insert(map<int, int>::value_type(iFE, FE_order));
0074 if (!t2.second)
0075 cout << " FE insertion failed...";
0076 pair<map<int, int>::iterator, bool> tt = FEmap.insert(map<int, int>::value_type(FE_order, inser));
0077 fe = tt.first;
0078 FE_index = (*fe).second;
0079 if (debug_)
0080 cout << "Build the Tower Block header for FE id " << iFE << " start at line " << rdsize << endl;
0081 if (debug_)
0082 cout << "This is the Fe number (order) " << number_FEs + 1 << endl;
0083 rawdata.resize(8 * rdsize + 8);
0084 unsigned char* pData = rawdata.data();
0085 pData[8 * FE_index] = iFE & 0xFF;
0086 pData[8 * FE_index + 1] = (nsamples & 0x7F);
0087 pData[8 * FE_index + 2] = bx & 0xFF;
0088 pData[8 * FE_index + 3] = (bx >> 8) & 0x0F;
0089 pData[8 * FE_index + 3] |= 0xa0;
0090 pData[8 * FE_index + 4] = lv1 & 0xFF;
0091 pData[8 * FE_index + 5] = (lv1 >> 8) & 0x0F;
0092 pData[8 * FE_index + 6] = 1;
0093 pData[8 * FE_index + 7] = 0xc0;
0094 if (debug_)
0095 print(rawdata);
0096 }
0097
0098
0099
0100 int istrip = elid.stripId();
0101 int ichannel = elid.xtalId();
0102
0103 if (debug_)
0104 cout << "Now add crystal : strip channel " << dec << istrip << " " << ichannel << endl;
0105
0106 unsigned char* pData = rawdata.data();
0107
0108 vector<unsigned char> vv(&pData[0], &pData[rawdata.size()]);
0109
0110 int n_add = 2 + 2 * nsamples;
0111 if (n_add % 8 != 0)
0112 n_add = n_add / 8 + 1;
0113 else
0114 n_add = n_add / 8;
0115 if (debug_)
0116 cout << "will add " << n_add << " lines of 64 bits at line " << (FE_index + 1) << endl;
0117 rawdata.resize(rawdata.size() + 8 * n_add);
0118 unsigned char* ppData = rawdata.data();
0119
0120 vector<unsigned char>::iterator iter = vv.begin() + 8 * (FE_index + 1);
0121
0122 vector<unsigned char> toadd(n_add * 8);
0123
0124 int tzs = 0;
0125 toadd[0] = (istrip & 0x7) + ((ichannel & 0x7) << 4);
0126 toadd[1] = (tzs & 0x1) << 12;
0127
0128 for (int isample = 0; isample < (n_add * 8 - 2) / 2; isample++) {
0129 if (isample < nsamples) {
0130 uint16_t word = (dataframe.sample(isample)).raw();
0131 toadd[2 + isample * 2] = word & 0x00FF;
0132 toadd[2 + isample * 2 + 1] = (word & 0xFF00) >> 8;
0133 } else {
0134 toadd[2 + isample * 2] = 0;
0135 toadd[2 + isample * 2 + 1] = 0;
0136 }
0137 if (isample % 2 == 0)
0138 toadd[2 + isample * 2 + 1] |= 0xc0;
0139 }
0140
0141 vv.insert(iter, toadd.begin(), toadd.end());
0142
0143
0144 for (int i = 0; i < (int)vv.size(); i++) {
0145 ppData[i] = vv[i];
0146 }
0147
0148 if (debug_) {
0149 cout << "pData for this FED is now " << endl;
0150 print(rawdata);
0151 }
0152
0153
0154 for (int i = FE_order + 1; i < (int)FEorder.size(); i++) {
0155 FEmap[i] += n_add;
0156 if (debug_)
0157 cout << "FEmap updated for fe number " << dec << i << endl;
0158 if (debug_)
0159 cout << " FEmap[" << i << "] = " << FEmap[i] << endl;
0160 }
0161
0162
0163 int blocklength = ppData[8 * FE_index + 6] + ((ppData[8 * FE_index + 7] & 0x1) << 8);
0164 blocklength += n_add;
0165 ppData[8 * FE_index + 6] = blocklength & 0xFF;
0166 ppData[8 * FE_index + 7] |= (blocklength & 0x100) >> 8;
0167 }
0168
0169 void TowerBlockFormatter::EndEvent(FEDRawDataCollection* productRawData) {
0170
0171
0172
0173
0174 if (debug_)
0175 cout << "enter in TowerBlockFormatter::EndEvent. First reorder the FE's. " << endl;
0176
0177 for (int idcc = 1; idcc <= 54; idcc++) {
0178
0179
0180
0181
0182 int FEDid = FEDNumbering::MINECALFEDID + idcc;
0183
0184 FEDRawData& fedData = productRawData->FEDData(FEDid);
0185 if (fedData.size() <= 16)
0186 continue;
0187
0188 if (debug_)
0189 cout << "This is FEDid = " << FEDid << endl;
0190
0191 unsigned char* pData = fedData.data();
0192
0193 Word64* words = reinterpret_cast<Word64*>(pData);
0194
0195 int length = fedData.size() / 8;
0196 int iDAQ_header(-1), iDCC_header(-1), iTCCBlock_header(-1), iSRBlock_header(-1), iTowerBlock_header(-1),
0197 iDAQ_trailer(-1);
0198
0199 for (int i = length - 1; i > -1; i--) {
0200 if (((words[i] >> 60) & 0xF) == 0x5)
0201 iDAQ_header = i;
0202 if (((words[i] >> 62) & 0x3) == 0x0)
0203 iDCC_header = i;
0204 if (((words[i] >> 61) & 0x7) == 0x3)
0205 iTCCBlock_header = i;
0206 if (((words[i] >> 61) & 0x7) == 0x4)
0207 iSRBlock_header = i;
0208 if (((words[i] >> 62) & 0x3) == 0x3)
0209 iTowerBlock_header = i;
0210 if (((words[i] >> 60) & 0xF) == 0xA)
0211 iDAQ_trailer = i;
0212 }
0213
0214 if (iTowerBlock_header < 0)
0215 iTowerBlock_header = iDAQ_trailer;
0216 if (iSRBlock_header < 0)
0217 iSRBlock_header = iTowerBlock_header;
0218 if (iTCCBlock_header < 0)
0219 iTCCBlock_header = iSRBlock_header;
0220
0221 if (debug_) {
0222 cout << "iDAQ_header = " << iDAQ_header << endl;
0223 cout << " iDCC_header = " << iDCC_header << endl;
0224 cout << " iTCCBlock_header = " << iTCCBlock_header << endl;
0225 cout << " iSRBlock_header = " << iSRBlock_header << endl;
0226 cout << " iTowerBlock_header = " << iTowerBlock_header << endl;
0227 cout << " iDAQ_trailer = " << iDAQ_trailer << endl;
0228 }
0229
0230 std::map<int, int> FrontEnd;
0231 std::map<int, std::vector<Word64> > Map_xtal_data;
0232
0233 int iTowerBlock_header_keep = iTowerBlock_header;
0234
0235 while (iTowerBlock_header < iDAQ_trailer) {
0236 int fe = words[iTowerBlock_header] & 0xFF;
0237 int nlines = (words[iTowerBlock_header] >> 48) & 0x1FF;
0238 if (debug_)
0239 cout << "This is FE number " << fe << "needs nlines = " << nlines << endl;
0240 FrontEnd[fe] = nlines;
0241 std::vector<Word64> xtal_data;
0242 for (int j = 0; j < nlines; j++) {
0243 Word64 ww = words[iTowerBlock_header + j];
0244 xtal_data.push_back(ww);
0245 }
0246 Map_xtal_data[fe] = xtal_data;
0247 iTowerBlock_header += nlines;
0248 }
0249
0250 if (debug_) {
0251 cout << "vector of FrontEnd : " << FrontEnd.size() << endl;
0252 for (std::map<int, int>::const_iterator it = FrontEnd.begin(); it != FrontEnd.end(); it++) {
0253 int fe = it->first;
0254 int l = it->second;
0255 cout << "FE line " << fe << " " << l << endl;
0256 }
0257 }
0258
0259 iTowerBlock_header = iTowerBlock_header_keep;
0260 for (std::map<int, int>::const_iterator it = FrontEnd.begin(); it != FrontEnd.end(); it++) {
0261 int fe = it->first;
0262 int nlines = it->second;
0263 if (debug_)
0264 cout << "iTowerBlock_header = " << iTowerBlock_header << endl;
0265 vector<Word64> xtal_data = Map_xtal_data[fe];
0266 for (int j = 0; j < nlines; j++) {
0267 words[iTowerBlock_header + j] = xtal_data[j];
0268 if (debug_)
0269 cout << "update line " << iTowerBlock_header + j << endl;
0270 }
0271 if (debug_) {
0272 int jFE = pData[8 * (iTowerBlock_header)];
0273 cout << "Front End on RD : " << jFE << endl;
0274 }
0275 iTowerBlock_header += nlines;
0276 }
0277
0278
0279
0280
0281
0282 if (debug_)
0283 cout << "now reorder the xtals within the FEs" << endl;
0284
0285 iTowerBlock_header = iTowerBlock_header_keep;
0286
0287 for (std::map<int, int>::const_iterator it = FrontEnd.begin(); it != FrontEnd.end(); it++) {
0288 int fe = it->first;
0289 if (fe > 68)
0290 cout << "Problem... fe = " << fe << " in FEDid = " << FEDid << endl;
0291 if (debug_)
0292 cout << " This is for FE = " << fe << endl;
0293 int nlines = it->second;
0294 int timesamples = pData[8 * iTowerBlock_header + 1] & 0x7F;
0295 int n4 = timesamples - 3;
0296 int n_lines4 = n4 / 4;
0297 if (n4 % 4 != 0)
0298 n_lines4++;
0299 if (n_lines4 < 0)
0300 n_lines4 = 0;
0301 int Nxtal_max = (nlines - 1) / (1 + n_lines4);
0302 int Nxtal = 0;
0303
0304 map<int, map<int, vector<Word64> > > Strip_Map;
0305
0306 while (Nxtal < Nxtal_max) {
0307 int i_xtal = iTowerBlock_header + 1 + Nxtal * (1 + n_lines4);
0308 int strip = words[i_xtal] & 0x7;
0309 int xtal = (words[i_xtal] >> 4) & 0x7;
0310
0311 map<int, map<int, vector<Word64> > >::iterator iit = Strip_Map.find(strip);
0312
0313 map<int, vector<Word64> > NewMap;
0314 map<int, vector<Word64> > Xtal_Map;
0315
0316 if (iit == Strip_Map.end()) {
0317 Xtal_Map = NewMap;
0318 } else {
0319 Xtal_Map = iit->second;
0320 }
0321
0322 std::vector<Word64> xtal_data;
0323 for (int j = 0; j < n_lines4 + 1; j++) {
0324 Word64 ww = words[i_xtal + j];
0325 xtal_data.push_back(ww);
0326 }
0327 Xtal_Map[xtal] = xtal_data;
0328 Strip_Map[strip] = Xtal_Map;
0329
0330 Nxtal++;
0331 }
0332
0333
0334
0335 int idx = 0;
0336 for (map<int, map<int, vector<Word64> > >::const_iterator jt = Strip_Map.begin(); jt != Strip_Map.end(); jt++) {
0337 int strip = jt->first;
0338 if (debug_)
0339 cout << " this is strip number " << strip << endl;
0340 map<int, vector<Word64> > Xtal_Map = jt->second;
0341
0342 for (map<int, vector<Word64> >::const_iterator kt = Xtal_Map.begin(); kt != Xtal_Map.end(); kt++) {
0343 int xtal = kt->first;
0344 if (debug_)
0345 cout << " this is xtal number " << xtal << endl;
0346 vector<Word64> xtal_data = kt->second;
0347
0348 int mlines = (int)xtal_data.size();
0349 if (debug_)
0350 cout << " mlines = " << mlines << endl;
0351 for (int j = 0; j < mlines; j++) {
0352 int line = iTowerBlock_header + 1 + idx + j;
0353 if (line >= iDAQ_trailer)
0354 cout << "smth wrong... line " << line << " trailer " << iDAQ_trailer << endl;
0355 words[line] = xtal_data[j];
0356 if (debug_)
0357 cout << " updated line " << iTowerBlock_header + idx + j << endl;
0358 }
0359 idx += mlines;
0360
0361 }
0362 Xtal_Map.clear();
0363
0364 }
0365
0366 Strip_Map.clear();
0367
0368 iTowerBlock_header += nlines;
0369 }
0370
0371 if (debug_)
0372 cout << " DONE FOR FED " << FEDid << endl;
0373 FrontEnd.clear();
0374 Map_xtal_data.clear();
0375
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 }
0387
0388 void TowerBlockFormatter::DigiToRaw(const EEDataFrame& dataframe,
0389 FEDRawData& rawdata,
0390 const EcalElectronicsMapping* TheMapping)
0391
0392
0393
0394
0395 {
0396
0397
0398 int bx = bx_;
0399 int lv1 = lv1_;
0400
0401 int rdsize = rawdata.size() / 8;
0402
0403 const EEDetId& eedetid = dataframe.id();
0404 EcalElectronicsId elid = TheMapping->getElectronicsId(eedetid);
0405 int DCCid = elid.dccId();
0406 int FEDid = FEDNumbering::MINECALFEDID + DCCid;
0407 int iFE = elid.towerId();
0408
0409 if (debug_)
0410 cout << "enter in TowerBlockFormatter::DigiToRaw DCCid FEDid iFE " << dec << DCCid << " " << FEDid << " " << iFE
0411 << endl;
0412
0413 int nsamples = dataframe.size();
0414
0415 if (iFE <= 0 || iFE > 68) {
0416 cout << "invalid iFE for EndCap DCCid iFE " << DCCid << " " << iFE << endl;
0417 return;
0418 }
0419
0420 map<int, map<int, int> >::iterator fen = FEDorder.find(FEDid);
0421 map<int, map<int, int> >::iterator fed = FEDmap.find(FEDid);
0422
0423 if (fen == FEDorder.end()) {
0424 if (debug_)
0425 cout << "New FED in TowerBlockFormatter " << dec << FEDid << " 0x" << hex << FEDid << endl;
0426 map<int, int> FEorder;
0427 pair<map<int, map<int, int> >::iterator, bool> t1 =
0428 FEDorder.insert(map<int, map<int, int> >::value_type(FEDid, FEorder));
0429 map<int, int> FEmap;
0430 pair<map<int, map<int, int> >::iterator, bool> t2 =
0431 FEDmap.insert(map<int, map<int, int> >::value_type(FEDid, FEmap));
0432 fen = t1.first;
0433 fed = t2.first;
0434 }
0435
0436 map<int, int>& FEorder = (*fen).second;
0437 map<int, int>& FEmap = (*fed).second;
0438
0439 map<int, int>::iterator fe = FEorder.find(iFE);
0440 int FE_order;
0441 int FE_index;
0442 if (fe != FEorder.end()) {
0443 FE_order = (*fe).second;
0444 map<int, int>::iterator ff = FEmap.find(FE_order);
0445 if (ff == FEmap.end())
0446 cout << "Error with maps... " << endl;
0447 FE_index = (*ff).second;
0448 if (debug_)
0449 cout << "FE already there, FE_index = " << dec << FE_index << " FEorder " << FE_order << endl;
0450 } else {
0451 if (debug_)
0452 cout << "New FE in TowerBlockFormatter FE " << dec << iFE << " 0x" << hex << iFE << " in FED id " << dec << FEDid
0453 << endl;
0454 int inser = rdsize;
0455 int number_FEs = FEorder.size() - 1;
0456 FE_order = number_FEs + 1;
0457 pair<map<int, int>::iterator, bool> t2 = FEorder.insert(map<int, int>::value_type(iFE, FE_order));
0458 if (!t2.second)
0459 cout << " FE insertion failed...";
0460 pair<map<int, int>::iterator, bool> tt = FEmap.insert(map<int, int>::value_type(FE_order, inser));
0461 fe = tt.first;
0462 FE_index = (*fe).second;
0463 if (debug_)
0464 cout << "Build the Tower Block header for FE id " << iFE << " start at line " << rdsize << endl;
0465 if (debug_)
0466 cout << "This is the Fe number (order) " << number_FEs + 1 << endl;
0467 rawdata.resize(8 * rdsize + 8);
0468 unsigned char* pData = rawdata.data();
0469
0470 pData[8 * FE_index] = iFE & 0xFF;
0471 pData[8 * FE_index + 1] = (nsamples & 0x7F);
0472 pData[8 * FE_index + 2] = bx & 0xFF;
0473 pData[8 * FE_index + 3] = (bx >> 8) & 0x0F;
0474 pData[8 * FE_index + 3] |= 0xa0;
0475 pData[8 * FE_index + 4] = lv1 & 0xFF;
0476 pData[8 * FE_index + 5] = (lv1 >> 8) & 0x0F;
0477 pData[8 * FE_index + 6] = 1;
0478 pData[8 * FE_index + 7] = 0xc0;
0479 if (debug_)
0480 print(rawdata);
0481 }
0482
0483
0484 int istrip = elid.stripId();
0485 int ichannel = elid.xtalId();
0486
0487 if (debug_)
0488 cout << "Now add crystal strip channel " << dec << istrip << " " << ichannel << endl;
0489
0490 unsigned char* pData = rawdata.data();
0491
0492 vector<unsigned char> vv(&pData[0], &pData[rawdata.size()]);
0493
0494 int n_add = 2 + 2 * nsamples;
0495 if (n_add % 8 != 0)
0496 n_add = n_add / 8 + 1;
0497 else
0498 n_add = n_add / 8;
0499 if (debug_)
0500 cout << "nsamples = " << dec << nsamples << endl;
0501 if (debug_)
0502 cout << "will add " << n_add << " lines of 64 bits at line " << (FE_index + 1) << endl;
0503 rawdata.resize(rawdata.size() + 8 * n_add);
0504 unsigned char* ppData = rawdata.data();
0505
0506 vector<unsigned char>::iterator iter = vv.begin() + 8 * (FE_index + 1);
0507
0508 vector<unsigned char> toadd(n_add * 8);
0509
0510 int tzs = 0;
0511 toadd[0] = (istrip & 0x7) + ((ichannel & 0x7) << 4);
0512 toadd[1] = (tzs & 0x1) << 12;
0513
0514 for (int isample = 0; isample < (n_add * 8 - 2) / 2; isample++) {
0515 if (isample < nsamples) {
0516 uint16_t word = (dataframe.sample(isample)).raw();
0517 toadd[2 + isample * 2] = word & 0x00FF;
0518 toadd[2 + isample * 2 + 1] = (word & 0xFF00) >> 8;
0519 } else {
0520 toadd[2 + isample * 2] = 0;
0521 toadd[2 + isample * 2 + 1] = 0;
0522 }
0523 if (isample % 2 == 0)
0524 toadd[2 + isample * 2 + 1] |= 0xc0;
0525 }
0526
0527 vv.insert(iter, toadd.begin(), toadd.end());
0528
0529
0530 for (int i = 0; i < (int)vv.size(); i++) {
0531 ppData[i] = vv[i];
0532 }
0533
0534 if (debug_) {
0535 cout << "pData for this FED is now " << endl;
0536 print(rawdata);
0537 }
0538
0539
0540 for (int i = FE_order + 1; i < (int)FEorder.size(); i++) {
0541 FEmap[i] += n_add;
0542 if (debug_)
0543 cout << "FEmap updated for fe number " << dec << i << endl;
0544 if (debug_)
0545 cout << " FEmap[" << i << "] = " << FEmap[i] << endl;
0546 }
0547
0548
0549 int blocklength = ppData[8 * FE_index + 6] + ((ppData[8 * FE_index + 7] & 0x1) << 8);
0550 blocklength += n_add;
0551 ppData[8 * FE_index + 6] = blocklength & 0xFF;
0552 ppData[8 * FE_index + 7] |= (blocklength & 0x100) >> 8;
0553 }