00001 #include "EventFilter/CSCRawToDigi/interface/CSCEventData.h"
00002 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBData.h"
00003 #include "DataFormats/CSCDigi/interface/CSCStripDigi.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "EventFilter/CSCRawToDigi/src/cscPackerCompare.h"
00006 #include <iostream>
00007 #include <iterator>
00008 #include "EventFilter/CSCRawToDigi/src/bitset_append.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010
00011
00012 bool CSCEventData::debug = false;
00013
00014 CSCEventData::CSCEventData(int chamberType) :
00015 theDMBHeader(),
00016 theALCTHeader(0),
00017 theAnodeData(0),
00018 theALCTTrailer(0),
00019 theTMBData(0),
00020 theDMBTrailer(),
00021 theChamberType(chamberType),
00022 alctZSErecovered(0),
00023 zseEnable(0)
00024 {
00025
00026 for(unsigned i = 0; i < 5; ++i) {
00027 theCFEBData[i] = 0;
00028 }
00029 }
00030
00031
00032 CSCEventData::CSCEventData(unsigned short * buf){
00033 unpack_data(buf);
00034 }
00035
00036
00037 void CSCEventData::unpack_data(unsigned short * buf)
00038 {
00039
00040 init();
00041 unsigned short * pos = buf;
00042 if(debug) {
00043 LogTrace ("CSCEventData|CSCRawToDigi") << "The event data ";
00044 for(int i = 0; i < 16; ++i){
00045 LogTrace ("CSCEventData|CSCRawToDigi") << std::hex << pos[i ] << " ";
00046 }
00047 }
00048
00049 theDMBHeader = CSCDMBHeader(pos);
00050 if(!(theDMBHeader.check())) {
00051 LogTrace ("CSCEventData|CSCRawToDigi") << "Bad DMB Header??? " << " first four words: ";
00052 for(int i = 0; i < 4; ++i){
00053 LogTrace ("CSCEventData|CSCRawToDigi") << std::hex << pos[i ] << " ";
00054 }
00055 }
00056
00057
00058 if (debug) {
00059 LogTrace ("CSCEventData|CSCRawToDigi") << "nalct = " << nalct();
00060 LogTrace ("CSCEventData|CSCRawToDigi") << "nclct = " << nclct();
00061 }
00062
00063 if (debug) {
00064 LogTrace ("CSCEventData|CSCRawToDigi") << "size in words of DMBHeader" << theDMBHeader.sizeInWords();
00065 LogTrace ("CSCEventData|CSCRawToDigi") << "sizeof(DMBHeader)" << sizeof(theDMBHeader);
00066 }
00067
00068 pos += theDMBHeader.sizeInWords();
00069
00070 if (nalct() ==1) {
00071 if (isALCT(pos)) {
00072 theALCTHeader = new CSCALCTHeader( pos );
00073 if(!theALCTHeader->check()){
00074 LogTrace ("CSCEventData|CSCRawToDigi") <<"+++WARNING: Corrupt ALCT data - won't attempt to decode";
00075 }
00076 else {
00077
00078 pos += theALCTHeader->sizeInWords();
00079
00080 theALCTHeader->ALCTDigis();
00081
00082
00083
00084
00086
00087
00088
00089
00091
00092
00093
00094
00095
00096
00097
00098
00100
00101 zseEnable = (theALCTHeader->data()[5] & 0x1000) >> 12;
00102
00103 int sizeInWord_ZSE =0;
00104
00105
00106
00107 if(zseEnable){
00110 int nWGs_per_layer = ( (theALCTHeader->data()[6]&0x0007) + 1 ) * 16 ;
00112 int nWG_round_up = int(nWGs_per_layer/12)+(nWGs_per_layer%3?1:0);
00113
00114 unsigned short * posZSE = pos;
00115 std::vector<unsigned short> alctZSErecoveredVector;
00116 alctZSErecoveredVector.clear();
00117
00118
00119
00120
00124
00125
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00138
00140 int alctZSErecoveredPos=0;
00141 while (*posZSE != 0xDE0D){
00142 if( (*posZSE == 0x1000) && (*posZSE != 0x3000)){
00143 for(int j=0; j<nWG_round_up; j++){
00144 alctZSErecoveredVector.push_back(0x0000);
00145 }
00146 alctZSErecoveredPos+=nWG_round_up;
00147 }
00148 else {
00149 alctZSErecoveredVector.push_back(*posZSE);
00150 ++alctZSErecoveredPos;
00151 }
00152 posZSE++;
00153 sizeInWord_ZSE++;
00154 }
00155
00156 alctZSErecovered = new unsigned short [alctZSErecoveredVector.size()];
00157
00159 for(int l=0; l<(int)alctZSErecoveredVector.size(); l++){
00160 alctZSErecovered[l]=alctZSErecoveredVector[l];
00161 }
00162
00163 unsigned short *posRecovered = alctZSErecovered;
00164 theAnodeData = new CSCAnodeData(*theALCTHeader, posRecovered);
00165
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 pos +=sizeInWord_ZSE;
00182 }
00183 else{
00184
00185 theAnodeData = new CSCAnodeData(*theALCTHeader, pos);
00186 pos += theAnodeData->sizeInWords();
00187 }
00188
00189 theALCTTrailer = new CSCALCTTrailer( pos );
00190 pos += theALCTTrailer->sizeInWords();
00191 }
00192 }
00193 else {
00194 LogTrace ("CSCEventData|CSCRawToDigi") << "Error:nalct reported but no ALCT data found!!!";
00195 }
00196 }
00197
00198 if (nclct() ==1) {
00199 if (isTMB(pos)) {
00200
00201 theTMBData = new CSCTMBData(pos);
00202 pos += theTMBData->size();
00203 }
00204 else {
00205 LogTrace ("CSCEventData|CSCRawToDigi") << "Error:nclct reported but no TMB data found!!!";
00206 }
00207 }
00208
00209
00210 bool dmbTrailerReached= false;
00211 for (int i=0; i<12000; ++i) {
00212 dmbTrailerReached =
00213 (*(i+pos) & 0xF000) == 0xF000 && (*(i+pos+1) & 0xF000) == 0xF000
00214 && (*(i+pos+2) & 0xF000) == 0xF000 && (*(i+pos+3) & 0xF000) == 0xF000
00215 && (*(i+pos+4) & 0xF000) == 0xE000 && (*(i+pos+5) & 0xF000) == 0xE000
00216 && (*(i+pos+6) & 0xF000) == 0xE000 && (*(i+pos+7) & 0xF000) == 0xE000;
00217 if (dmbTrailerReached) {
00218 theDMBTrailer = *( (CSCDMBTrailer *) (pos+i) );
00219 break;
00220 }
00221 }
00222 if (dmbTrailerReached) {
00223 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00224 theCFEBData[icfeb] = 0;
00225 int cfeb_available = theDMBHeader.cfebAvailable(icfeb);
00226 unsigned int cfebTimeout = theDMBTrailer.cfeb_starttimeout | theDMBTrailer.cfeb_endtimeout;
00227
00228 if ( cfeb_available==1 ) {
00229 if ((cfebTimeout >> icfeb) & 1) {
00230 if (debug) LogTrace ("CSCEventData|CSCRawToDigi") << "CFEB Timed out! ";
00231 } else {
00232
00233
00234 theCFEBData[icfeb] = new CSCCFEBData(icfeb, pos);
00235 pos += theCFEBData[icfeb]->sizeInWords();
00236 }
00237 }
00238 }
00239 pos += theDMBTrailer.sizeInWords();
00240 size_ = pos-buf;
00241 }
00242 else {
00243 LogTrace ("CSCEventData|CSCRawToDigi") << "Critical Error: DMB Trailer was not found!!! ";
00244 }
00245 }
00246
00247 bool CSCEventData::isALCT(const short unsigned int * buf) {
00248 return (((buf[0]&0xFFFF)==0xDB0A)||(((buf[0]&0xF800)==0x6000)&&((buf[1]&0xF800)==0)));
00249 }
00250
00251 bool CSCEventData::isTMB(const short unsigned int * buf) {
00252 return ((buf[0]&0xFFF)==0xB0C);
00253 }
00254
00255
00256
00257 CSCEventData::CSCEventData(const CSCEventData & data) {
00258 copy(data);
00259 }
00260
00261 CSCEventData::~CSCEventData() {
00262 destroy();
00263 }
00264
00265
00266 CSCEventData CSCEventData::operator=(const CSCEventData & data) {
00267
00268 if(&data != this) destroy();
00269 copy(data);
00270 return *this;
00271 }
00272
00273
00274 void CSCEventData::init() {
00275
00276 theALCTHeader = 0;
00277 theAnodeData = 0;
00278 theALCTTrailer = 0;
00279 theTMBData = 0;
00280 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00281 theCFEBData[icfeb] = 0;
00282 }
00283 alctZSErecovered=0;
00284 zseEnable=0;
00285 }
00286
00287
00288 void CSCEventData::copy(const CSCEventData & data) {
00289 init();
00290 theDMBHeader = data.theDMBHeader;
00291 theDMBTrailer = data.theDMBTrailer;
00292 if(data.theALCTHeader != NULL)
00293 theALCTHeader = new CSCALCTHeader(*(data.theALCTHeader));
00294 if(data.theAnodeData != NULL)
00295 theAnodeData = new CSCAnodeData(*(data.theAnodeData));
00296 if(data.theALCTTrailer != NULL)
00297 theALCTTrailer = new CSCALCTTrailer(*(data.theALCTTrailer));
00298 if(data.theTMBData != NULL)
00299 theTMBData = new CSCTMBData(*(data.theTMBData));
00300 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00301 theCFEBData[icfeb] = 0;
00302 if(data.theCFEBData[icfeb] != NULL)
00303 theCFEBData[icfeb] = new CSCCFEBData(*(data.theCFEBData[icfeb]));
00304 }
00305 size_ = data.size_;
00306 theChamberType = data.theChamberType;
00307
00308 }
00309
00310
00311 void CSCEventData::destroy() {
00312 if(zseEnable){
00313 delete [] alctZSErecovered;
00314 }
00315 delete theALCTHeader;
00316 delete theAnodeData;
00317 delete theALCTTrailer;
00318 delete theTMBData;
00319 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00320 delete theCFEBData[icfeb];
00321 }
00322
00323
00324
00325
00326
00327 }
00328
00329
00330 std::vector<CSCStripDigi> CSCEventData::stripDigis(const CSCDetId & idlayer) const {
00331 std::vector<CSCStripDigi> result;
00332 for(unsigned icfeb = 0; icfeb < 5; ++icfeb){
00333 std::vector<CSCStripDigi> newDigis = stripDigis(idlayer, icfeb);
00334 result.insert(result.end(), newDigis.begin(), newDigis.end());
00335 }
00336 return result;
00337 }
00338
00339
00340 std::vector<CSCStripDigi> CSCEventData::stripDigis(unsigned idlayer, unsigned icfeb) const {
00341
00342 std::vector<CSCStripDigi> result;
00343 if(theCFEBData[icfeb] != NULL) {
00344 std::vector<CSCStripDigi> newDigis = theCFEBData[icfeb]->digis(idlayer);
00345 result.insert(result.end(), newDigis.begin(), newDigis.end());
00346 }
00347
00348 return result;
00349 }
00350
00351
00352 std::vector<CSCWireDigi> CSCEventData::wireDigis(unsigned ilayer) const {
00353 if(theAnodeData == 0) {
00354 return std::vector<CSCWireDigi>();
00355 }
00356 else {
00357 return theAnodeData->wireDigis(ilayer);
00358 }
00359 }
00360
00361
00362 std::vector < std::vector<CSCStripDigi> > CSCEventData::stripDigis() const {
00363 std::vector < std::vector<CSCStripDigi> > result;
00364 for (int layer = 1; layer <= 6; ++layer) {
00365 std::vector<CSCStripDigi> digis = stripDigis(layer);
00366 result.push_back(digis);
00367 }
00368 return result;
00369 }
00370
00371 std::vector < std::vector<CSCWireDigi> > CSCEventData::wireDigis() const {
00372 std::vector < std::vector<CSCWireDigi> > result;
00373 for (int layer = 1; layer <= 6; ++layer) {
00374 result.push_back(wireDigis(layer));
00375 }
00376 return result;
00377 }
00378
00379
00380 CSCCFEBData* CSCEventData::cfebData(unsigned icfeb) const {
00381 return theCFEBData[icfeb];
00382 }
00383
00384
00385 CSCALCTHeader* CSCEventData::alctHeader() const{
00386 if(nalct() == 0) throw cms::Exception("No ALCT for this chamber");
00387 return theALCTHeader;
00388 }
00389
00390 CSCALCTTrailer * CSCEventData::alctTrailer() const{
00391 if(nalct() == 0) throw cms::Exception("No ALCT for this chamber");
00392 return theALCTTrailer;
00393 }
00394
00395
00396 CSCAnodeData * CSCEventData::alctData() const {
00397 if(nalct() == 0) throw cms::Exception("No ALCT for this chamber");
00398 return theAnodeData;
00399 }
00400
00401 CSCTMBData * CSCEventData::tmbData() const {
00402 if(nclct() == 0) throw cms::Exception("No CLCT for this chamber");
00403 return theTMBData;
00404 }
00405
00406
00407 CSCTMBHeader * CSCEventData::tmbHeader() const {
00408 if((nclct() == 0)||(tmbData()==NULL)) throw cms::Exception("No CLCT header for this chamber");
00409 return tmbData()->tmbHeader();
00410 }
00411
00412 CSCCLCTData * CSCEventData::clctData() const {
00413 if((nclct() == 0)||(tmbData()==NULL)) throw cms::Exception("No CLCT data for this chamber");
00414 return tmbData()->clctData();
00415 }
00416
00417
00418 void CSCEventData::setEventInformation(int bxnum, int lvl1num) {
00419 theDMBHeader.setBXN(bxnum);
00420 theDMBHeader.setL1A(lvl1num);
00421 if(theALCTHeader) {
00422 theALCTHeader->setEventInformation(theDMBHeader);
00423 }
00424 if(theTMBData) {
00425 theTMBData->tmbHeader()->setEventInformation(theDMBHeader);
00426 }
00427 }
00428
00429
00430 void CSCEventData::checkALCTClasses() {
00431 if(theAnodeData == NULL)
00432 {
00433 assert(theChamberType>0);
00434 theALCTHeader = new CSCALCTHeader(theChamberType);
00435 theALCTHeader->setEventInformation(theDMBHeader);
00436 theAnodeData = new CSCAnodeData(*theALCTHeader);
00437 int size = theALCTHeader->sizeInWords() + theAnodeData->sizeInWords() + CSCALCTTrailer::sizeInWords();
00438 theALCTTrailer = new CSCALCTTrailer(size, theALCTHeader->alctFirmwareVersion());
00439
00440 theDMBHeader.addNALCT();
00441 }
00442 }
00443
00444
00445 void CSCEventData::checkTMBClasses()
00446 {
00447 if(theTMBData == NULL) {
00448 theTMBData = new CSCTMBData();
00449 theTMBData->tmbHeader()->setEventInformation(theDMBHeader);
00450 theDMBHeader.addNCLCT();
00451 }
00452 }
00453
00454
00455 void CSCEventData::add(const CSCStripDigi & digi, int layer) {
00456
00457 unsigned cfeb = (digi.getStrip()-1)/16;
00458 bool sixteenSamples = false;
00459 if (digi.getADCCounts().size()==16) sixteenSamples = true;
00460 if(theCFEBData[cfeb] == 0) {
00461 theCFEBData[cfeb] = new CSCCFEBData(cfeb, sixteenSamples);
00462 theDMBHeader.addCFEB(cfeb);
00463 }
00464 theCFEBData[cfeb]->add(digi, layer);
00465 }
00466
00467
00468 void CSCEventData::add(const CSCWireDigi & digi, int layer) {
00469 checkALCTClasses();
00470 theAnodeData->add(digi, layer);
00471 theALCTHeader->setDAVForChannel(digi.getWireGroup());
00472 }
00473
00474 void CSCEventData::add(const CSCComparatorDigi & digi, int layer) {
00475 checkTMBClasses();
00476 theTMBData->clctData()->add(digi, layer);
00477 }
00478
00479
00480
00481 void CSCEventData::add(const std::vector<CSCALCTDigi> & digis) {
00482 checkALCTClasses();
00483 theALCTHeader->add(digis);
00484 }
00485
00486
00487 void CSCEventData::add(const std::vector<CSCCLCTDigi> & digis) {
00488 checkTMBClasses();
00489 theTMBData->tmbHeader()->add(digis);
00490 }
00491
00492 void CSCEventData::add(const std::vector<CSCCorrelatedLCTDigi> & digis) {
00493 checkTMBClasses();
00494 theTMBData->tmbHeader()->add(digis);
00495 }
00496
00497
00498
00499
00500 std::ostream & operator<<(std::ostream & os, const CSCEventData & evt) {
00501 for(int ilayer = 1; ilayer <= 6; ++ilayer) {
00502 std::vector<CSCStripDigi> stripDigis = evt.stripDigis(ilayer);
00503
00504
00505 std::vector<CSCWireDigi> wireDigis = evt.wireDigis(ilayer);
00506
00507 }
00508 return os;
00509 }
00510
00511 boost::dynamic_bitset<> CSCEventData::pack() {
00512 boost::dynamic_bitset<> result = bitset_utilities::ushortToBitset( theDMBHeader.sizeInWords()*16,
00513 theDMBHeader.data());
00514
00515 if(theALCTHeader != NULL) {
00516 boost::dynamic_bitset<> alctHeader = theALCTHeader->pack();
00517 result = bitset_utilities::append(result, alctHeader);
00518 }
00519 if(theAnodeData != NULL) {
00520 boost::dynamic_bitset<> anodeData = bitset_utilities::ushortToBitset (theAnodeData->sizeInWords()*16,
00521 theAnodeData->data());
00522 result = bitset_utilities::append(result, anodeData);
00523 }
00524 if(theALCTTrailer != NULL) {
00525 boost::dynamic_bitset<> alctTrailer =bitset_utilities::ushortToBitset(theALCTTrailer->sizeInWords()*16,
00526 theALCTTrailer->data());
00527 result = bitset_utilities::append(result, alctTrailer);
00528 }
00529 if(theTMBData != NULL) {
00530 result = bitset_utilities::append(result, theTMBData->pack());
00531 }
00532
00533 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00534 if(theCFEBData[icfeb] != NULL){
00535 boost::dynamic_bitset<> cfebData = bitset_utilities::ushortToBitset(theCFEBData[icfeb]->sizeInWords()*16,
00536 theCFEBData[icfeb]->data());
00537 result = bitset_utilities::append(result, cfebData);
00538 }
00539 }
00540
00541 boost::dynamic_bitset<> dmbTrailer = bitset_utilities::ushortToBitset( theDMBTrailer.sizeInWords()*16,
00542 theDMBTrailer.data());
00543 result = bitset_utilities::append(result, dmbTrailer);
00544 return result;
00545 }
00546
00547
00548 void CSCEventData::selfTest() {
00549 CSCEventData chamberData(5);
00550 CSCDetId detId(1, 3, 2, 1, 3);
00551 std::vector<CSCCLCTDigi> clctDigis;
00552
00553
00554 clctDigis.push_back(CSCCLCTDigi(1, 1, 4, 1, 0, 30, 3, 2, 1));
00555 clctDigis.push_back(CSCCLCTDigi(1, 1, 2, 1, 1, 31, 1, 2, 2));
00556
00557
00558
00559 std::vector<CSCCorrelatedLCTDigi> corrDigis;
00560 corrDigis.push_back(CSCCorrelatedLCTDigi(1, 1, 2, 10, 98, 5, 0, 1, 0, 0, 0, 0));
00561 corrDigis.push_back(CSCCorrelatedLCTDigi(2, 1, 2, 20, 15, 9, 1, 0, 0, 0, 0, 0));
00562
00563 chamberData.add(clctDigis);
00564 chamberData.add(corrDigis);
00565
00566 CSCWireDigi wireDigi(10, 6);
00567 CSCComparatorDigi comparatorDigi(30, 1, 6);
00568 chamberData.add(wireDigi, 3);
00569 chamberData.add(comparatorDigi, 3);
00570
00571 CSCEventData newData = cscPackAndUnpack(chamberData);
00572
00573 std::vector<CSCCLCTDigi> clcts = newData.tmbHeader()->CLCTDigis(detId.rawId());
00574 assert(cscPackerCompare(clcts[0],clctDigis[0]));
00575 assert(cscPackerCompare(clcts[1],clctDigis[1]));
00576
00577 std::vector<CSCCorrelatedLCTDigi> lcts = newData.tmbHeader()->CorrelatedLCTDigis(detId.rawId());
00578 assert(cscPackerCompare(lcts[0], corrDigis[0]));
00579 assert(cscPackerCompare(lcts[1], corrDigis[1]));
00580
00581
00582 CSCDetId me1adet1(1, 1, 1, 4, 1);
00583 CSCDetId me1bdet1(1, 1, 4, 4, 6);
00584 CSCDetId me1adet2(2, 1, 1, 4, 2);
00585 CSCDetId me1bdet2(2, 1, 4, 4, 5);
00586
00587 std::vector<int> sca(16, 600);
00588 std::vector<unsigned short> overflow(16, 0), overlap(16, 0), errorfl(16,0);
00589 CSCStripDigi me1a(5, sca, overflow, overlap, errorfl);
00590 CSCStripDigi me1b(8, sca, overflow, overlap, errorfl);
00591
00592 CSCEventData forward(1);
00593 CSCEventData backward(1);
00594
00595 forward.add(me1a, me1adet1.layer());
00596 forward.add(me1b, me1bdet1.layer());
00597 backward.add(me1a, me1adet2.layer());
00598 backward.add(me1b, me1adet2.layer());
00599 std::vector<CSCStripDigi> me1afs = forward.stripDigis(me1adet1);
00600 std::vector<CSCStripDigi> me1bfs = forward.stripDigis(me1bdet1);
00601 std::vector<CSCStripDigi> me1abs = backward.stripDigis(me1adet2);
00602 std::vector<CSCStripDigi> me1bbs = backward.stripDigis(me1bdet2);
00603
00604
00605 assert(me1afs.size() == 16);
00606 assert(me1bfs.size() == 16);
00607 assert(me1abs.size() == 16);
00608 assert(me1bbs.size() == 16);
00609
00610 assert(me1afs[4].getStrip() == 5);
00611 assert(me1bfs[7].getStrip() == 8);
00612 assert(me1abs[4].getStrip() == 5);
00613 assert(me1bbs[7].getStrip() == 8);
00614 assert(me1afs[4].pedestal() == 600);
00615 assert(me1bfs[7].pedestal() == 600);
00616 assert(me1abs[4].pedestal() == 600);
00617 assert(me1bbs[7].pedestal() == 600);
00618
00619
00620 }