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
00023 for(unsigned i = 0; i < 5; ++i) {
00024 theCFEBData[i] = 0;
00025 }
00026 }
00027
00028
00029 CSCEventData::CSCEventData(unsigned short * buf){
00030
00031 init();
00032 unsigned short * pos = buf;
00033 if(debug) {
00034 LogTrace ("CSCEventData|CSCRawToDigi") << "The event data ";
00035 for(int i = 0; i < 16; ++i){
00036 LogTrace ("CSCEventData|CSCRawToDigi") << std::hex << pos[i ] << " ";
00037 }
00038 }
00039
00040 theDMBHeader = CSCDMBHeader(pos);
00041 if(!(theDMBHeader.check())) {
00042 LogTrace ("CSCEventData|CSCRawToDigi") << "Bad DMB Header??? " << " first four words: ";
00043 for(int i = 0; i < 4; ++i){
00044 LogTrace ("CSCEventData|CSCRawToDigi") << std::hex << pos[i ] << " ";
00045 }
00046 }
00047
00048
00049 if (debug) {
00050 LogTrace ("CSCEventData|CSCRawToDigi") << "nalct = " << nalct();
00051 LogTrace ("CSCEventData|CSCRawToDigi") << "nclct = " << nclct();
00052 }
00053
00054 if (debug) {
00055 LogTrace ("CSCEventData|CSCRawToDigi") << "size in words of DMBHeader" << theDMBHeader.sizeInWords();
00056 LogTrace ("CSCEventData|CSCRawToDigi") << "sizeof(DMBHeader)" << sizeof(theDMBHeader);
00057 }
00058
00059 pos += theDMBHeader.sizeInWords();
00060
00061 if (nalct() ==1) {
00062 if (isALCT(pos)) {
00063 theALCTHeader = new CSCALCTHeader( pos );
00064 if(!theALCTHeader->check()){
00065 LogTrace ("CSCEventData|CSCRawToDigi") <<"+++WARNING: Corrupt ALCT data - won't attempt to decode";
00066 }
00067 else {
00068
00069 pos += theALCTHeader->sizeInWords();
00070
00071 theALCTHeader->ALCTDigis();
00072 theAnodeData = new CSCAnodeData(*theALCTHeader, pos);
00073 pos += theAnodeData->sizeInWords();
00074 theALCTTrailer = new CSCALCTTrailer( pos );
00075 pos += theALCTTrailer->sizeInWords();
00076 }
00077 }
00078 else {
00079 LogTrace ("CSCEventData|CSCRawToDigi") << "Error:nalct reported but no ALCT data found!!!";
00080 }
00081 }
00082
00083 if (nclct() ==1) {
00084 if (isTMB(pos)) {
00085
00086 theTMBData = new CSCTMBData(pos);
00087 pos += theTMBData->size();
00088 }
00089 else {
00090 LogTrace ("CSCEventData|CSCRawToDigi") << "Error:nclct reported but no TMB data found!!!";
00091 }
00092 }
00093
00094
00095 bool dmbTrailerReached= false;
00096 for (int i=0; i<12000; ++i) {
00097 dmbTrailerReached =
00098 (*(i+pos) & 0xF000) == 0xF000 && (*(i+pos+1) & 0xF000) == 0xF000
00099 && (*(i+pos+2) & 0xF000) == 0xF000 && (*(i+pos+3) & 0xF000) == 0xF000
00100 && (*(i+pos+4) & 0xF000) == 0xE000 && (*(i+pos+5) & 0xF000) == 0xE000
00101 && (*(i+pos+6) & 0xF000) == 0xE000 && (*(i+pos+7) & 0xF000) == 0xE000;
00102 if (dmbTrailerReached) {
00103 theDMBTrailer = *( (CSCDMBTrailer *) (pos+i) );
00104 break;
00105 }
00106 }
00107 if (dmbTrailerReached) {
00108 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00109 theCFEBData[icfeb] = 0;
00110 int cfeb_available = theDMBHeader.cfebAvailable(icfeb);
00111 unsigned int cfebTimeout = theDMBTrailer.cfeb_starttimeout | theDMBTrailer.cfeb_endtimeout;
00112
00113 if ( cfeb_available==1 ) {
00114 if ((cfebTimeout >> icfeb) & 1) {
00115 if (debug) LogTrace ("CSCEventData|CSCRawToDigi") << "CFEB Timed out! ";
00116 } else {
00117
00118
00119 theCFEBData[icfeb] = new CSCCFEBData(icfeb, pos);
00120 pos += theCFEBData[icfeb]->sizeInWords();
00121 }
00122 }
00123 }
00124 pos += theDMBTrailer.sizeInWords();
00125 size_ = pos-buf;
00126 }
00127 else {
00128 LogTrace ("CSCEventData|CSCRawToDigi") << "Critical Error: DMB Trailer was not found!!! ";
00129 }
00130 }
00131
00132 bool CSCEventData::isALCT(const short unsigned int * buf) {
00133 return (((buf[0]&0xFFFF)==0xDB0A)||(((buf[0]&0xF800)==0x6000)&&((buf[1]&0xF800)==0)));
00134 }
00135
00136 bool CSCEventData::isTMB(const short unsigned int * buf) {
00137 return ((buf[0]&0xFFF)==0xB0C);
00138 }
00139
00140
00141
00142 CSCEventData::CSCEventData(const CSCEventData & data) {
00143 copy(data);
00144 }
00145
00146 CSCEventData::~CSCEventData() {
00147 destroy();
00148 }
00149
00150
00151 CSCEventData CSCEventData::operator=(const CSCEventData & data) {
00152
00153 if(&data != this) destroy();
00154 copy(data);
00155 return *this;
00156 }
00157
00158
00159 void CSCEventData::init() {
00160
00161 theALCTHeader = 0;
00162 theAnodeData = 0;
00163 theALCTTrailer = 0;
00164 theTMBData = 0;
00165 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00166 theCFEBData[icfeb] = 0;
00167 }
00168 }
00169
00170
00171 void CSCEventData::copy(const CSCEventData & data) {
00172 init();
00173 theDMBHeader = data.theDMBHeader;
00174 theDMBTrailer = data.theDMBTrailer;
00175 if(data.theALCTHeader != NULL)
00176 theALCTHeader = new CSCALCTHeader(*(data.theALCTHeader));
00177 if(data.theAnodeData != NULL)
00178 theAnodeData = new CSCAnodeData(*(data.theAnodeData));
00179 if(data.theALCTTrailer != NULL)
00180 theALCTTrailer = new CSCALCTTrailer(*(data.theALCTTrailer));
00181 if(data.theTMBData != NULL)
00182 theTMBData = new CSCTMBData(*(data.theTMBData));
00183 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00184 theCFEBData[icfeb] = 0;
00185 if(data.theCFEBData[icfeb] != NULL)
00186 theCFEBData[icfeb] = new CSCCFEBData(*(data.theCFEBData[icfeb]));
00187 }
00188 size_ = data.size_;
00189 theChamberType = data.theChamberType;
00190
00191 }
00192
00193
00194 void CSCEventData::destroy() {
00195 delete theALCTHeader;
00196 delete theAnodeData;
00197 delete theALCTTrailer;
00198 delete theTMBData;
00199 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00200 delete theCFEBData[icfeb];
00201 }
00202 }
00203
00204
00205 std::vector<CSCStripDigi> CSCEventData::stripDigis(unsigned ilayer) const {
00206 assert(ilayer > 0 && ilayer <= 6);
00207 std::vector<CSCStripDigi> result;
00208 for(unsigned icfeb = 0; icfeb < 5; ++icfeb){
00209 if(theCFEBData[icfeb] != NULL) {
00210 std::vector<CSCStripDigi> newDigis = theCFEBData[icfeb]->digis(ilayer);
00211 result.insert(result.end(), newDigis.begin(), newDigis.end());
00212 }
00213 }
00214
00215 return result;
00216 }
00217
00218
00219 std::vector<CSCStripDigi> CSCEventData::stripDigis(unsigned idlayer, unsigned icfeb) const {
00220
00221 std::vector<CSCStripDigi> result;
00222 if(theCFEBData[icfeb] != NULL) {
00223 std::vector<CSCStripDigi> newDigis = theCFEBData[icfeb]->digis(idlayer);
00224 result.insert(result.end(), newDigis.begin(), newDigis.end());
00225 }
00226
00227
00228 return result;
00229 }
00230
00231
00232 std::vector<CSCWireDigi> CSCEventData::wireDigis(unsigned ilayer) const {
00233 if(theAnodeData == 0) {
00234 return std::vector<CSCWireDigi>();
00235 }
00236 else {
00237 return theAnodeData->wireDigis(ilayer);
00238 }
00239 }
00240
00241
00242 std::vector < std::vector<CSCStripDigi> > CSCEventData::stripDigis() const {
00243 std::vector < std::vector<CSCStripDigi> > result;
00244 for (int layer = 1; layer <= 6; ++layer) {
00245 std::vector<CSCStripDigi> digis = stripDigis(layer);
00246 result.push_back(digis);
00247 }
00248 return result;
00249 }
00250
00251 std::vector < std::vector<CSCWireDigi> > CSCEventData::wireDigis() const {
00252 std::vector < std::vector<CSCWireDigi> > result;
00253 for (int layer = 1; layer <= 6; ++layer) {
00254 result.push_back(wireDigis(layer));
00255 }
00256 return result;
00257 }
00258
00259
00260 CSCCFEBData* CSCEventData::cfebData(unsigned icfeb) const {
00261 return theCFEBData[icfeb];
00262 }
00263
00264
00265 CSCALCTHeader* CSCEventData::alctHeader() const{
00266 if(nalct() == 0) throw cms::Exception("No ALCT for this chamber");
00267 return theALCTHeader;
00268 }
00269
00270 CSCALCTTrailer * CSCEventData::alctTrailer() const{
00271 if(nalct() == 0) throw cms::Exception("No ALCT for this chamber");
00272 return theALCTTrailer;
00273 }
00274
00275
00276 CSCAnodeData * CSCEventData::alctData() const {
00277 if(nalct() == 0) throw cms::Exception("No ALCT for this chamber");
00278 return theAnodeData;
00279 }
00280
00281 CSCTMBData * CSCEventData::tmbData() const {
00282 if(nclct() == 0) throw cms::Exception("No CLCT for this chamber");
00283 return theTMBData;
00284 }
00285
00286
00287 CSCTMBHeader * CSCEventData::tmbHeader() const {
00288 if((nclct() == 0)||(tmbData()==NULL)) throw cms::Exception("No CLCT header for this chamber");
00289 return tmbData()->tmbHeader();
00290 }
00291
00292 CSCCLCTData * CSCEventData::clctData() const {
00293 if((nclct() == 0)||(tmbData()==NULL)) throw cms::Exception("No CLCT data for this chamber");
00294 return tmbData()->clctData();
00295 }
00296
00297
00298 void CSCEventData::setEventInformation(int bxnum, int lvl1num) {
00299 theDMBHeader.setBXN(bxnum);
00300 theDMBHeader.setL1A(lvl1num);
00301 if(theALCTHeader) {
00302 theALCTHeader->setEventInformation(theDMBHeader);
00303 }
00304 if(theTMBData) {
00305 theTMBData->tmbHeader()->setEventInformation(theDMBHeader);
00306 }
00307 }
00308
00309
00310 void CSCEventData::checkALCTClasses() {
00311 if(theAnodeData == NULL)
00312 {
00313 assert(theChamberType>0);
00314 theALCTHeader = new CSCALCTHeader(theChamberType);
00315 theALCTHeader->setEventInformation(theDMBHeader);
00316 theAnodeData = new CSCAnodeData(*theALCTHeader);
00317 int size = theALCTHeader->sizeInWords() + theAnodeData->sizeInWords() + CSCALCTTrailer::sizeInWords();
00318 int firmwareVersion = 2006;
00319 theALCTTrailer = new CSCALCTTrailer(size, firmwareVersion);
00320
00321 theDMBHeader.addNALCT();
00322 }
00323 }
00324
00325
00326 void CSCEventData::checkTMBClasses()
00327 {
00328 if(theTMBData == NULL) {
00329 theTMBData = new CSCTMBData();
00330 theTMBData->tmbHeader()->setEventInformation(theDMBHeader);
00331 theDMBHeader.addNCLCT();
00332 }
00333 }
00334
00335
00336 void CSCEventData::add(const CSCStripDigi & digi, int layer) {
00337
00338 unsigned cfeb = (digi.getStrip()-1)/16;
00339 bool sixteenSamples = false;
00340 if (digi.getADCCounts().size()==16) sixteenSamples = true;
00341 if(theCFEBData[cfeb] == 0) {
00342 theCFEBData[cfeb] = new CSCCFEBData(cfeb, sixteenSamples);
00343 theDMBHeader.addCFEB(cfeb);
00344 }
00345 theCFEBData[cfeb]->add(digi, layer);
00346 }
00347
00348
00349 void CSCEventData::add(const CSCWireDigi & digi, int layer) {
00350 checkALCTClasses();
00351 theAnodeData->add(digi, layer);
00352 theALCTHeader->setDAVForChannel(digi.getWireGroup());
00353 }
00354
00355 void CSCEventData::add(const CSCComparatorDigi & digi, int layer) {
00356 checkTMBClasses();
00357 theTMBData->clctData()->add(digi, layer);
00358 }
00359
00360
00361
00362 void CSCEventData::add(const std::vector<CSCALCTDigi> & digis) {
00363 checkALCTClasses();
00364 theALCTHeader->add(digis);
00365 }
00366
00367
00368 void CSCEventData::add(const std::vector<CSCCLCTDigi> & digis) {
00369 checkTMBClasses();
00370 theTMBData->tmbHeader()->add(digis);
00371 }
00372
00373 void CSCEventData::add(const std::vector<CSCCorrelatedLCTDigi> & digis) {
00374 checkTMBClasses();
00375 theTMBData->tmbHeader()->add(digis);
00376 }
00377
00378
00379
00380
00381 std::ostream & operator<<(std::ostream & os, const CSCEventData & evt) {
00382 for(int ilayer = 1; ilayer <= 6; ++ilayer) {
00383 std::vector<CSCStripDigi> stripDigis = evt.stripDigis(ilayer);
00384
00385
00386 std::vector<CSCWireDigi> wireDigis = evt.wireDigis(ilayer);
00387
00388 }
00389 return os;
00390 }
00391
00392 boost::dynamic_bitset<> CSCEventData::pack() {
00393 boost::dynamic_bitset<> result = bitset_utilities::ushortToBitset( theDMBHeader.sizeInWords()*16,
00394 theDMBHeader.data());
00395
00396 if(theALCTHeader != NULL) {
00397 boost::dynamic_bitset<> alctHeader = theALCTHeader->pack();
00398 result = bitset_utilities::append(result, alctHeader);
00399 }
00400 if(theAnodeData != NULL) {
00401 boost::dynamic_bitset<> anodeData = bitset_utilities::ushortToBitset (theAnodeData->sizeInWords()*16,
00402 theAnodeData->data());
00403 result = bitset_utilities::append(result, anodeData);
00404 }
00405 if(theALCTTrailer != NULL) {
00406 boost::dynamic_bitset<> alctTrailer =bitset_utilities::ushortToBitset(theALCTTrailer->sizeInWords()*16,
00407 theALCTTrailer->data());
00408 result = bitset_utilities::append(result, alctTrailer);
00409 }
00410 if(theTMBData != NULL) {
00411 result = bitset_utilities::append(result, theTMBData->pack());
00412 }
00413
00414 for(int icfeb = 0; icfeb < 5; ++icfeb) {
00415 if(theCFEBData[icfeb] != NULL){
00416 boost::dynamic_bitset<> cfebData = bitset_utilities::ushortToBitset(theCFEBData[icfeb]->sizeInWords()*16,
00417 theCFEBData[icfeb]->data());
00418 result = bitset_utilities::append(result, cfebData);
00419 }
00420 }
00421
00422 boost::dynamic_bitset<> dmbTrailer = bitset_utilities::ushortToBitset( theDMBTrailer.sizeInWords()*16,
00423 theDMBTrailer.data());
00424 result = bitset_utilities::append(result, dmbTrailer);
00425 return result;
00426 }
00427
00428
00429 void CSCEventData::selfTest() {
00430 CSCEventData chamberData(5);
00431 CSCDetId detId(1, 3, 2, 1, 3);
00432 std::vector<CSCCLCTDigi> clctDigis;
00433
00434
00435 clctDigis.push_back(CSCCLCTDigi(1, 1, 4, 1, 0, 30, 3, 2, 1));
00436 clctDigis.push_back(CSCCLCTDigi(1, 1, 2, 1, 1, 31, 1, 2, 2));
00437
00438
00439
00440 std::vector<CSCCorrelatedLCTDigi> corrDigis;
00441 corrDigis.push_back(CSCCorrelatedLCTDigi(1, 1, 2, 10, 98, 5, 0, 1, 0, 0, 0, 0));
00442 corrDigis.push_back(CSCCorrelatedLCTDigi(2, 1, 2, 20, 15, 9, 1, 0, 0, 0, 0, 0));
00443
00444 chamberData.add(clctDigis);
00445 chamberData.add(corrDigis);
00446
00447 CSCWireDigi wireDigi(10, 6);
00448 CSCComparatorDigi comparatorDigi(30, 1, 6);
00449 chamberData.add(wireDigi, 3);
00450 chamberData.add(comparatorDigi, 3);
00451
00452 CSCEventData newData = cscPackAndUnpack(chamberData);
00453
00454 std::vector<CSCCLCTDigi> clcts = newData.tmbHeader()->CLCTDigis(detId.rawId());
00455 assert(cscPackerCompare(clcts[0],clctDigis[0]));
00456 assert(cscPackerCompare(clcts[1],clctDigis[1]));
00457
00458 std::vector<CSCCorrelatedLCTDigi> lcts = newData.tmbHeader()->CorrelatedLCTDigis(detId.rawId());
00459 assert(cscPackerCompare(lcts[0], corrDigis[0]));
00460 assert(cscPackerCompare(lcts[1], corrDigis[1]));
00461
00462
00463 CSCDetId me1adet1(1, 1, 1, 4, 1);
00464 CSCDetId me1bdet1(1, 1, 4, 4, 6);
00465 CSCDetId me1adet2(2, 1, 1, 4, 2);
00466 CSCDetId me1bdet2(2, 1, 4, 4, 5);
00467
00468 std::vector<int> sca(16, 600);
00469 std::vector<unsigned short> overflow(16, 0), overlap(16, 0), errorfl(16,0);
00470 CSCStripDigi me1a(5, sca, overflow, overlap, errorfl);
00471 CSCStripDigi me1b(8, sca, overflow, overlap, errorfl);
00472
00473 CSCEventData forward(1);
00474 CSCEventData backward(1);
00475
00476 forward.add(me1a, me1adet1.layer());
00477 forward.add(me1b, me1bdet1.layer());
00478 backward.add(me1a, me1adet2.layer());
00479 backward.add(me1b, me1adet2.layer());
00480
00481 std::vector<CSCStripDigi> me1afs = forward.stripDigis(me1adet1.layer());
00482 std::vector<CSCStripDigi> me1bfs = forward.stripDigis(me1bdet1.layer());
00483 std::vector<CSCStripDigi> me1abs = backward.stripDigis(me1adet2.layer());
00484 std::vector<CSCStripDigi> me1bbs = backward.stripDigis(me1bdet2.layer());
00485
00486
00487
00488 assert(me1afs.size() == 16);
00489 assert(me1bfs.size() == 16);
00490 assert(me1abs.size() == 16);
00491 assert(me1bbs.size() == 16);
00492 assert(me1afs[4].getStrip() == 5);
00493 assert(me1bfs[7].getStrip() == 8);
00494 assert(me1abs[4].getStrip() == 5);
00495 assert(me1bbs[7].getStrip() == 8);
00496 assert(me1afs[4].pedestal() == 600);
00497 assert(me1bfs[7].pedestal() == 600);
00498 assert(me1abs[4].pedestal() == 600);
00499 assert(me1bbs[7].pedestal() == 600);
00500
00501
00502 }