CMS 3D CMS Logo

CSCEventData.cc

Go to the documentation of this file.
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   // zero everything
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)) {//checking for ALCTData
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         //dataPresent|=0x40;
00069         pos += theALCTHeader->sizeInWords(); //size of the header
00070         //fill ALCT Digis
00071         theALCTHeader->ALCTDigis();    
00072         theAnodeData = new CSCAnodeData(*theALCTHeader, pos);  
00073         pos += theAnodeData->sizeInWords(); // size of the data is determined during unpacking
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       //dataPresent|=0x20;
00086       theTMBData = new CSCTMBData(pos);  //fill all TMB data
00087       pos += theTMBData->size();
00088     }
00089     else {
00090       LogTrace ("CSCEventData|CSCRawToDigi") << "Error:nclct reported but no TMB data found!!!";
00091     }
00092   }
00093 
00094   //now let's try to find and unpack the DMBTrailer
00095   bool dmbTrailerReached= false;
00096   for (int i=0; i<12000; ++i) {//8000 max for cfeb + 1980ALCT + 287 TMB
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       //cfeb_available cannot be trusted - need additional verification!
00113       if ( cfeb_available==1 )   {
00114         if ((cfebTimeout >> icfeb) & 1) {
00115           if (debug) LogTrace ("CSCEventData|CSCRawToDigi") << "CFEB Timed out! ";
00116         } else {
00117           //dataPresent|=(0x1>>icfeb);
00118           // Fill CFEB data and convert it into cathode digis
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   // check for self-assignment before destructing
00153   if(&data != this) destroy();
00154   copy(data);
00155   return *this;
00156 }
00157 
00158 
00159 void CSCEventData::init() {
00160   //dataPresent = 0;
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   //  assert(ilayer > 0 && ilayer <= 6); // off because now idlayer is raw cscdetid
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     // set data available flag
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   //@@ need special logic here for ME11
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     //copy(stripDigis.begin(), stripDigis.end(), std::ostream_iterator<CSCStripDigi>(os, "\n"));
00385     //print your scas here
00386     std::vector<CSCWireDigi> wireDigis = evt.wireDigis(ilayer);
00387     //copy(wireDigis.begin(), wireDigis.end(), std::ostream_iterator<CSCWireDigi>(os, "\n"));
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   // Both CLCTs are read-out at the same (pre-trigger) bx, so the last-but-one
00434   // arguments in both digis must be the same.
00435   clctDigis.push_back(CSCCLCTDigi(1, 1, 4, 1, 0, 30, 3, 2, 1)); // valid for 2007
00436   clctDigis.push_back(CSCCLCTDigi(1, 1, 2, 1, 1, 31, 1, 2, 2));
00437   
00438   // BX of LCT (8th argument) is 1-bit word (the least-significant bit
00439   // of ALCT's bx).
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   // test strip digis
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   //FIXME The current code works under the assumption that ME11 and ME1A
00487   // go into separate EventData.  They need to be combined.
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 }

Generated on Tue Jun 9 17:34:24 2009 for CMSSW by  doxygen 1.5.4