00001 #include <memory>
00002 #include <list>
00003
00004
00005
00006 #include "EventFilter/EcalDigiToRaw/interface/TowerBlockFormatter.h"
00007
00008 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00009 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
00010 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00011
00012 using namespace std;
00013
00014
00015 TowerBlockFormatter::TowerBlockFormatter() {
00016
00017 }
00018
00019 TowerBlockFormatter::~TowerBlockFormatter() {
00020
00021 }
00022
00023
00024
00025 void TowerBlockFormatter::DigiToRaw(const EBDataFrame& dataframe, FEDRawData& rawdata,
00026 const EcalElectronicsMapping* TheMapping)
00027
00028 {
00029
00030 int bx = *pbx_;
00031 int lv1 = *plv1_ - 1;
00032
00033
00034 int rdsize = rawdata.size() / 8;
00035
00036 const EBDetId& ebdetid = dataframe.id();
00037
00038 int DCCid = TheMapping -> DCCid(ebdetid);
00039 int FEDid = FEDNumbering::MINECALFEDID + DCCid ;
00040
00041
00042 int nsamples = dataframe.size();
00043
00044 const EcalElectronicsId& elid = TheMapping -> getElectronicsId(ebdetid);
00045 int iFE = elid.towerId();
00046 if (iFE <= 0 || iFE > 68) throw cms::Exception("InvalidFEid") <<
00047 "TowerBlockFormatter::DigiToRaw : Invalid iFE " << iFE << endl;
00048
00049
00050 map<int, map<int,int> >::iterator fen = FEDorder -> find(FEDid);
00051 map<int, map<int,int> >::iterator fed = FEDmap -> find(FEDid);
00052
00053 if (fen == FEDorder -> end()) {
00054 if (debug_) cout << "New FED in TowerBlockFormatter " << dec << FEDid << " 0x" << hex << FEDid << endl;
00055 map<int,int> FEorder;
00056 pair<map<int, map<int,int> >::iterator, bool> t1 = FEDorder -> insert(map<int, map<int,int> >::value_type(FEDid,FEorder));
00057 map<int,int> FEmap;
00058 pair<map<int, map<int,int> >::iterator, bool> t2 = FEDmap -> insert(map<int, map<int,int> >::value_type(FEDid,FEmap));
00059 fen = t1.first;
00060 fed = t2.first;
00061 }
00062
00063 map<int, int>& FEorder = (*fen).second;
00064 map<int, int>& FEmap = (*fed).second;
00065
00066 map<int,int>::iterator fe = FEorder.find(iFE);
00067 int FE_order;
00068 int FE_index;
00069 if (fe != FEorder.end()) {
00070 FE_order = (*fe).second;
00071 map<int,int>::iterator ff = FEmap.find(FE_order);
00072 if (ff == FEmap.end()) cout << "Error with maps... " << endl;
00073 FE_index = (*ff).second;
00074 if (debug_) cout << "FE already there, FE_index = " << dec << FE_index << " FEorder " << FE_order << endl;
00075 }
00076 else {
00077 if (debug_) cout << "New FE in TowerBlockFormatter FE " << dec << iFE << " 0x" << hex << iFE << " in FED id " << dec << FEDid << endl;
00078 int inser = rdsize;
00079 int number_FEs = FEorder.size() -1;
00080 FE_order = number_FEs+1;
00081 pair<map<int,int>::iterator, bool> t2 = FEorder.insert(map<int,int>::value_type(iFE,FE_order));
00082 if (! t2.second) cout << " FE insertion failed...";
00083 pair<map<int,int>::iterator, bool> tt = FEmap.insert(map<int,int>::value_type(FE_order,inser));
00084 fe = tt.first;
00085 FE_index = (*fe).second;
00086 if (debug_) cout << "Build the Tower Block header for FE id " << iFE << " start at line " << rdsize << endl;
00087 if (debug_) cout << "This is the Fe number (order) " << number_FEs+1 << endl;
00088 rawdata.resize( 8*rdsize + 8);
00089 unsigned char* pData = rawdata.data();
00090 pData[8*FE_index] = iFE & 0xFF;
00091 pData[8*FE_index+1] = (nsamples & 0x7F);
00092 pData[8*FE_index+2] = bx & 0xFF;
00093 pData[8*FE_index+3] = (bx >>8) & 0x0F;
00094 pData[8*FE_index+3] |= 0xa0;
00095 pData[8*FE_index+4] = lv1 & 0xFF;
00096 pData[8*FE_index+5] = (lv1 >>8) & 0x0F;
00097 pData[8*FE_index+6] = 1;
00098 pData[8*FE_index+7] = 0xc0;
00099 if (debug_) print(rawdata);
00100
00101 }
00102
00103
00104
00105
00106 int istrip = elid.stripId();
00107 int ichannel = elid.xtalId();
00108
00109 if (debug_) cout << "Now add crystal : strip channel " << dec << istrip << " " << ichannel << endl;
00110
00111
00112 unsigned char* pData = rawdata.data();
00113
00114 vector<unsigned char> vv(&pData[0],&pData[rawdata.size()]);
00115
00116
00117 int n_add = 2 + 2*nsamples;
00118 if (n_add % 8 != 0) n_add = n_add/8 +1;
00119 else
00120 n_add = n_add/8;
00121 if (debug_) cout << "will add " << n_add << " lines of 64 bits at line " << (FE_index+1) << endl;
00122 rawdata.resize( rawdata.size() + 8*n_add );
00123 unsigned char* ppData = rawdata.data();
00124
00125 vector<unsigned char>::iterator iter = vv.begin() + 8*(FE_index+1);
00126
00127 vector<unsigned char> toadd(n_add*8);
00128
00129
00130 int tzs=0;
00131 toadd[0] = (istrip & 0x7) + ((ichannel & 0x7)<<4);
00132 toadd[1] = (tzs & 0x1) <<12;
00133
00134 for (int isample=0; isample < (n_add*8-2)/2; isample++) {
00135 if (isample < nsamples) {
00136 uint16_t word = (dataframe.sample(isample)).raw();
00137 toadd[2 + isample*2] = word & 0x00FF;
00138 toadd[2 + isample*2 +1] = (word & 0xFF00)>>8;
00139 }
00140 else {
00141 toadd[2 + isample*2] = 0;
00142 toadd[2 + isample*2 +1] = 0;
00143 }
00144 if (isample % 2 == 0) toadd[2 + isample*2 +1] |= 0xc0;
00145 }
00146
00147 vv.insert(iter,toadd.begin(),toadd.end());
00148
00149
00150
00151 for (int i=0; i < (int)vv.size(); i++) {
00152 ppData[i] = vv[i];
00153 }
00154
00155 if (debug_) {
00156 cout << "pData for this FED is now " << endl;
00157 print(rawdata);
00158 }
00159
00160
00161 for (int i=FE_order+1; i < (int)FEorder.size(); i++) {
00162 FEmap[i] += n_add;
00163 if (debug_) cout << "FEmap updated for fe number " << dec << i << endl;
00164 if (debug_) cout << " FEmap[" << i << "] = " << FEmap[i] << endl;
00165 }
00166
00167
00168 int blocklength = ppData[8*FE_index+6]
00169 + ((ppData[8*FE_index+7] & 0x1)<<8);
00170 blocklength += n_add;
00171 ppData[8*FE_index+6] = blocklength & 0xFF;
00172 ppData[8*FE_index+7] |= (blocklength & 0x100)>>8;
00173
00174
00175
00176 }
00177
00178
00179
00180 void TowerBlockFormatter::EndEvent(FEDRawDataCollection* productRawData) {
00181
00182
00183
00184
00185
00186 if (debug_) cout << "enter in TowerBlockFormatter::EndEvent. First reorder the FE's. " << endl;
00187
00188 for (int idcc=1; idcc <= 54; idcc++) {
00189
00190
00191
00192
00193
00194 int FEDid = FEDNumbering::MINECALFEDID + idcc;
00195
00196 FEDRawData& fedData = productRawData -> FEDData(FEDid);
00197 if (fedData.size() <= 16) continue;
00198
00199 if (debug_) cout << "This is FEDid = " << FEDid << endl;
00200
00201 unsigned char * pData = fedData.data();
00202
00203 Word64* words = reinterpret_cast<Word64*>(pData);
00204
00205 int length = fedData.size() / 8;
00206 int iDAQ_header(-1), iDCC_header(-1), iTCCBlock_header(-1),
00207 iSRBlock_header(-1), iTowerBlock_header(-1), iDAQ_trailer(-1);
00208
00209 for (int i=length-1; i > -1; i--) {
00210 if ( ( (words[i] >> 60) & 0xF) == 0x5 ) iDAQ_header=i;
00211 if ( ( (words[i] >> 62) & 0x3) == 0x0 ) iDCC_header=i;
00212 if ( ( (words[i] >> 61) & 0x7) == 0x3 ) iTCCBlock_header=i;
00213 if ( ( (words[i] >> 61) & 0x7) == 0x4 ) iSRBlock_header=i;
00214 if ( ( (words[i] >> 62) & 0x3) == 0x3 ) iTowerBlock_header=i;
00215 if ( ( (words[i] >> 60) & 0xF) == 0xA ) iDAQ_trailer=i;
00216 }
00217
00218 if (iTowerBlock_header < 0) iTowerBlock_header = iDAQ_trailer;
00219 if (iSRBlock_header < 0) iSRBlock_header = iTowerBlock_header;
00220 if (iTCCBlock_header < 0) iTCCBlock_header = iSRBlock_header;
00221
00222 if (debug_) {
00223 cout << "iDAQ_header = " << iDAQ_header << endl;
00224 cout << " iDCC_header = " << iDCC_header << endl;
00225 cout << " iTCCBlock_header = " << iTCCBlock_header << endl;
00226 cout << " iSRBlock_header = " << iSRBlock_header << endl;
00227 cout << " iTowerBlock_header = " << iTowerBlock_header << endl;
00228 cout << " iDAQ_trailer = " << iDAQ_trailer << endl;
00229 }
00230
00231 std::map<int, int> FrontEnd;
00232 std::map<int, std::vector<Word64> > Map_xtal_data;
00233
00234 int iTowerBlock_header_keep = iTowerBlock_header;
00235
00236 while (iTowerBlock_header < iDAQ_trailer) {
00237 int fe = words[iTowerBlock_header] & 0xFF;
00238 int nlines = (words[iTowerBlock_header] >> 48) & 0x1FF;
00239 if (debug_) cout << "This is FE number " << fe << "needs nlines = " << nlines << endl;
00240 FrontEnd[fe] = nlines;
00241 std::vector<Word64> xtal_data;
00242 for (int j=0; j < nlines; j++) {
00243 Word64 ww = words[iTowerBlock_header+j];
00244 xtal_data.push_back(ww);
00245 }
00246 Map_xtal_data[fe] = xtal_data;
00247 iTowerBlock_header += nlines;
00248 }
00249
00250 if (debug_) {
00251 cout << "vector of FrontEnd : " << FrontEnd.size() << endl;
00252 for (std::map<int, int>::const_iterator it=FrontEnd.begin();
00253 it != FrontEnd.end(); it++) {
00254 int fe = it -> first;
00255 int l = it -> second;
00256 cout << "FE line " << fe << " " << l << endl;
00257 }
00258 }
00259
00260 iTowerBlock_header = iTowerBlock_header_keep;
00261 for (std::map<int, int>::const_iterator it=FrontEnd.begin();
00262 it != FrontEnd.end(); it++) {
00263 int fe = it -> first;
00264 int nlines = it -> second;
00265 if (debug_) cout << "iTowerBlock_header = " << iTowerBlock_header << endl;
00266 vector<Word64> xtal_data = Map_xtal_data[fe];
00267 for (int j=0; j < nlines; j++) {
00268 words[iTowerBlock_header+j] = xtal_data[j];
00269 if (debug_) cout << "update line " << iTowerBlock_header+j << endl;
00270 }
00271 if (debug_) {
00272 int jFE = pData[8*(iTowerBlock_header)];
00273 cout << "Front End on RD : " << jFE << endl;
00274 }
00275 iTowerBlock_header += nlines;
00276 }
00277
00278
00279
00280
00281
00282 if (debug_) cout << "now reorder the xtals within the FEs" << endl;
00283
00284 iTowerBlock_header = iTowerBlock_header_keep;
00285
00286 for (std::map<int, int>::const_iterator it=FrontEnd.begin();
00287 it != FrontEnd.end(); it++) {
00288
00289 int fe = it -> first;
00290 if (fe > 68) cout << "Problem... fe = " << fe << " in FEDid = " << FEDid << endl;
00291 if (debug_) cout << " This is for FE = " << fe << endl;
00292 int nlines = it -> second;
00293 int timesamples = pData[8*iTowerBlock_header+1] & 0x7F;
00294 int n4=timesamples-3;
00295 int n_lines4 = n4/4;
00296 if ( n4 % 4 != 0) n_lines4 ++;
00297 if (n_lines4<0) n_lines4=0;
00298 int Nxtal_max = (nlines-1)/(1+n_lines4);
00299 int Nxtal = 0;
00300
00301 map< int, map<int, vector<Word64> > > Strip_Map;
00302
00303 while (Nxtal < Nxtal_max) {
00304
00305 int i_xtal = iTowerBlock_header+1 + Nxtal*(1+n_lines4);
00306 int strip = words[i_xtal] & 0x7;
00307 int xtal = ( words[i_xtal] >>4) & 0x7;
00308
00309 map< int, map<int, vector<Word64> > >::iterator iit = Strip_Map.find(strip);
00310
00311 map<int, vector<Word64> > NewMap;
00312 map<int, vector<Word64> > Xtal_Map;
00313
00314 if (iit == Strip_Map.end()) {
00315 Xtal_Map = NewMap;
00316 }
00317 else {
00318 Xtal_Map = iit -> second;
00319 }
00320
00321 std::vector<Word64> xtal_data;
00322 for (int j=0; j < n_lines4 +1; j++) {
00323 Word64 ww = words[i_xtal +j];
00324 xtal_data.push_back(ww);
00325 }
00326 Xtal_Map[xtal] = xtal_data;
00327 Strip_Map[strip] = Xtal_Map;
00328
00329 Nxtal ++;
00330 }
00331
00332
00333
00334 int idx = 0;
00335 for (map< int, map<int, vector<Word64> > >::const_iterator jt = Strip_Map.begin();
00336 jt != Strip_Map.end(); jt++) {
00337
00338 int strip = jt -> first;
00339 if (debug_) cout << " this is strip number " << strip << endl;
00340 map<int, vector<Word64> > Xtal_Map = jt -> second;
00341
00342 for (map<int, vector<Word64> >::const_iterator kt = Xtal_Map.begin();
00343 kt != Xtal_Map.end(); kt++) {
00344 int xtal = kt -> first;
00345 if (debug_) cout << " this is xtal number " << xtal << endl;
00346 vector<Word64> xtal_data = kt -> second;
00347
00348 int mlines = (int)xtal_data.size();
00349 if (debug_) cout << " mlines = " << mlines << endl;
00350 for (int j=0; j < mlines; j++) {
00351 int line = iTowerBlock_header+1+idx+j;
00352 if (line >= iDAQ_trailer) cout << "smth wrong... line " << line << " trailer " << iDAQ_trailer << endl;
00353 words[line] = xtal_data[j] ;
00354 if (debug_) cout << " updated line " << iTowerBlock_header+idx+j << endl;
00355 }
00356 idx += mlines;
00357
00358 }
00359 Xtal_Map.clear();
00360
00361 }
00362
00363 Strip_Map.clear();
00364
00365 iTowerBlock_header += nlines;
00366 }
00367
00368
00369 if (debug_) cout << " DONE FOR FED " << FEDid << endl;
00370 FrontEnd.clear();
00371 Map_xtal_data.clear();
00372
00373 }
00374
00375
00376
00377
00378
00379
00380
00381 FEDmap -> clear();
00382 FEDorder -> clear();
00383 delete FEDmap;
00384 delete FEDorder;
00385 FEDmap = 0;
00386 FEDorder = 0;
00387
00388 debug_ = false;
00389
00390
00391 }
00392
00393 void TowerBlockFormatter::StartEvent() {
00394
00395 FEDmap = new map<int, map<int,int> >;
00396 FEDorder = new map<int, map<int,int> >;
00397
00398 }
00399
00400
00401
00402
00403 void TowerBlockFormatter::DigiToRaw(const EEDataFrame& dataframe, FEDRawData& rawdata, const EcalElectronicsMapping* TheMapping)
00404
00405
00406
00407
00408 {
00409
00410
00411
00412 int bx = *pbx_;
00413 int lv1 = *plv1_;
00414
00415
00416 int rdsize = rawdata.size() / 8;
00417
00418 const EEDetId& eedetid = dataframe.id();
00419 EcalElectronicsId elid = TheMapping -> getElectronicsId(eedetid);
00420 int DCCid = elid.dccId();
00421 int FEDid = FEDNumbering::MINECALFEDID + DCCid ;
00422 int iFE = elid.towerId();
00423
00424 if (debug_) cout << "enter in TowerBlockFormatter::DigiToRaw DCCid FEDid iFE " <<
00425 dec << DCCid << " " << FEDid << " " << iFE << endl;
00426
00427 int nsamples = dataframe.size();
00428
00429 if (iFE <= 0 || iFE > 68) {
00430 cout << "invalid iFE for EndCap DCCid iFE " << DCCid << " " << iFE << endl;
00431 return;
00432 }
00433
00434
00435 map<int, map<int,int> >::iterator fen = FEDorder -> find(FEDid);
00436 map<int, map<int,int> >::iterator fed = FEDmap -> find(FEDid);
00437
00438 if (fen == FEDorder -> end()) {
00439 if (debug_) cout << "New FED in TowerBlockFormatter " << dec << FEDid << " 0x" << hex << FEDid << endl;
00440 map<int,int> FEorder;
00441 pair<map<int, map<int,int> >::iterator, bool> t1 = FEDorder -> insert(map<int, map<int,int> >::value_type(FEDid,FEorder));
00442 map<int,int> FEmap;
00443 pair<map<int, map<int,int> >::iterator, bool> t2 = FEDmap -> insert(map<int, map<int,int> >::value_type(FEDid,FEmap));
00444 fen = t1.first;
00445 fed = t2.first;
00446 }
00447
00448 map<int, int>& FEorder = (*fen).second;
00449 map<int, int>& FEmap = (*fed).second;
00450
00451 map<int,int>::iterator fe = FEorder.find(iFE);
00452 int FE_order;
00453 int FE_index;
00454 if (fe != FEorder.end()) {
00455 FE_order = (*fe).second;
00456 map<int,int>::iterator ff = FEmap.find(FE_order);
00457 if (ff == FEmap.end()) cout << "Error with maps... " << endl;
00458 FE_index = (*ff).second;
00459 if (debug_) cout << "FE already there, FE_index = " << dec << FE_index << " FEorder " << FE_order << endl;
00460 }
00461 else {
00462 if (debug_) cout << "New FE in TowerBlockFormatter FE " << dec << iFE << " 0x" << hex << iFE << " in FED id " << dec << FEDid << endl;
00463 int inser = rdsize;
00464 int number_FEs = FEorder.size() -1;
00465 FE_order = number_FEs+1;
00466 pair<map<int,int>::iterator, bool> t2 = FEorder.insert(map<int,int>::value_type(iFE,FE_order));
00467 if (! t2.second) cout << " FE insertion failed...";
00468 pair<map<int,int>::iterator, bool> tt = FEmap.insert(map<int,int>::value_type(FE_order,inser));
00469 fe = tt.first;
00470 FE_index = (*fe).second;
00471 if (debug_) cout << "Build the Tower Block header for FE id " << iFE << " start at line " << rdsize << endl;
00472 if (debug_) cout << "This is the Fe number (order) " << number_FEs+1 << endl;
00473 rawdata.resize( 8*rdsize + 8);
00474 unsigned char* pData = rawdata.data();
00475
00476 pData[8*FE_index] = iFE & 0xFF;
00477 pData[8*FE_index+1] = (nsamples & 0x7F);
00478 pData[8*FE_index+2] = bx & 0xFF;
00479 pData[8*FE_index+3] = (bx >>8) & 0x0F;
00480 pData[8*FE_index+3] |= 0xa0;
00481 pData[8*FE_index+4] = lv1 & 0xFF;
00482 pData[8*FE_index+5] = (lv1 >>8) & 0x0F;
00483 pData[8*FE_index+6] = 1;
00484 pData[8*FE_index+7] = 0xc0;
00485 if (debug_) print(rawdata);
00486
00487 }
00488
00489
00490
00491
00492 int istrip = elid.stripId();
00493 int ichannel = elid.xtalId();
00494
00495 if (debug_) cout << "Now add crystal strip channel " << dec << istrip << " " << ichannel << endl;
00496
00497 unsigned char* pData = rawdata.data();
00498
00499 vector<unsigned char> vv(&pData[0],&pData[rawdata.size()]);
00500
00501
00502 int n_add = 2 + 2*nsamples;
00503 if (n_add % 8 != 0) n_add = n_add/8 +1;
00504 else
00505 n_add = n_add/8;
00506 if (debug_) cout << "nsamples = " << dec << nsamples << endl;
00507 if (debug_) cout << "will add " << n_add << " lines of 64 bits at line " << (FE_index+1) << endl;
00508 rawdata.resize( rawdata.size() + 8*n_add );
00509 unsigned char* ppData = rawdata.data();
00510
00511 vector<unsigned char>::iterator iter = vv.begin() + 8*(FE_index+1);
00512
00513 vector<unsigned char> toadd(n_add*8);
00514
00515
00516 int tzs=0;
00517 toadd[0] = (istrip & 0x7) + ((ichannel & 0x7)<<4);
00518 toadd[1] = (tzs & 0x1) <<12;
00519
00520 for (int isample=0; isample < (n_add*8-2)/2; isample++) {
00521 if (isample < nsamples) {
00522 uint16_t word = (dataframe.sample(isample)).raw();
00523 toadd[2 + isample*2] = word & 0x00FF;
00524 toadd[2 + isample*2 +1] = (word & 0xFF00)>>8;
00525 }
00526 else {
00527 toadd[2 + isample*2] = 0;
00528 toadd[2 + isample*2 +1] = 0;
00529 }
00530 if (isample % 2 == 0) toadd[2 + isample*2 +1] |= 0xc0;
00531 }
00532
00533 vv.insert(iter,toadd.begin(),toadd.end());
00534
00535
00536
00537 for (int i=0; i < (int)vv.size(); i++) {
00538 ppData[i] = vv[i];
00539 }
00540
00541 if (debug_) {
00542 cout << "pData for this FED is now " << endl;
00543 print(rawdata);
00544 }
00545
00546
00547 for (int i=FE_order+1; i < (int)FEorder.size(); i++) {
00548 FEmap[i] += n_add;
00549 if (debug_) cout << "FEmap updated for fe number " << dec << i << endl;
00550 if (debug_) cout << " FEmap[" << i << "] = " << FEmap[i] << endl;
00551 }
00552
00553
00554 int blocklength = ppData[8*FE_index+6]
00555 + ((ppData[8*FE_index+7] & 0x1)<<8);
00556 blocklength += n_add;
00557 ppData[8*FE_index+6] = blocklength & 0xFF;
00558 ppData[8*FE_index+7] |= (blocklength & 0x100)>>8;
00559
00560
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571