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