CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/CSCRawToDigi/src/CSCCFEBData.cc

Go to the documentation of this file.
00001 
00002 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00003 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBData.h"
00004 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBTimeSlice.h"
00005 #include "EventFilter/CSCRawToDigi/interface/CSCBadCFEBTimeSlice.h"
00006 #include "DataFormats/CSCDigi/interface/CSCStripDigi.h"
00007 #include "DataFormats/CSCDigi/interface/CSCCFEBStatusDigi.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include <cassert>
00010 
00011 CSCCFEBData::CSCCFEBData(unsigned number, unsigned short * buf) 
00012   : theSize(0), boardNumber_(number), theNumberOfSamples(0) {
00013   // I may be grabbing too many words, but that's OK
00014   // parse for time slices
00015   unsigned pos = 0;
00016   // to be set later
00017   unsigned maxSamples = 8;
00018   theSliceStarts.reserve(8);
00019   while(theNumberOfSamples < maxSamples) {
00020     // first see if it's a bad slice
00021     CSCBadCFEBTimeSlice * badSlice
00022       = reinterpret_cast<CSCBadCFEBTimeSlice *>(buf+pos);
00023     if(badSlice->check()) {
00024       //show that a bad slice starts here
00025       theSliceStarts.push_back(std::pair<int, bool>(pos, false));
00026       pos += badSlice->sizeInWords();
00027       //store bad word for status digis
00028       bWords.push_back(badSlice->word(1).data()); //all 4 words are assumed identical so saving #1 only  
00029     } 
00030     else {
00031       // OK.  Maybe it's good.
00032       CSCCFEBTimeSlice * goodSlice 
00033         = reinterpret_cast<CSCCFEBTimeSlice *>(buf+pos);
00034       if(goodSlice->check()) {
00035         // show that a good slice starts here
00036         theSliceStarts.push_back(std::pair<int, bool>(pos, true));
00037         // it will just be an array of CSCCFEBTimeSlices, so we'll
00038         // grab the number of time slices from the first good one
00039         maxSamples =   goodSlice->sixteenSamples() ? 16 : 8;
00040         pos += goodSlice->sizeInWords();
00041       } 
00042       else {
00043         LogTrace ("CSCCFEBData|CSCRawToDigi") 
00044           << "CORRUPT CFEB DATA slice " << theNumberOfSamples << std::hex << " " 
00045           << *(buf+pos+3) << " " << *(buf+pos+2) << " "  << *(buf+pos+1) << " "<< *(buf+pos);
00046         //ok slice is bad but try another one at 100 words after it
00047         theSliceStarts.push_back(std::pair<int, bool>(pos, false));
00048         pos += 100;
00049       }
00050     }
00051     ++theNumberOfSamples;
00052   }
00053   theSize = pos;
00054   memcpy(theData, buf, theSize*2);
00055 }
00056 
00057 
00058 CSCCFEBData::CSCCFEBData(unsigned number, bool sixteenSamples) 
00059 : boardNumber_(number), theNumberOfSamples(sixteenSamples ? 16 : 8)
00060 {
00061   theSliceStarts.reserve(theNumberOfSamples);
00062 
00063   // fill the SCA controller words
00064   CSCCFEBSCAControllerWord scaWord;
00065   scaWord.ts_flag = sixteenSamples;
00066 
00067   // make a template slice to copy into theData buffer
00068   CSCCFEBTimeSlice slice;
00069   slice.setControllerWord(scaWord);
00070 
00071   for(unsigned i = 0; i < theNumberOfSamples; ++i) 
00072     {
00073       unsigned short * pos = theData+i*100;
00074       memcpy(pos, &slice, 200);
00075       theSliceStarts.push_back(std::pair<int,bool>(i*100, true));
00076     }
00077   theSize = theNumberOfSamples*100;
00078 }
00079 
00080 void CSCCFEBData::add(const CSCStripDigi & digi, int layer)
00081 {
00082   std::vector<int> scaCounts =  digi.getADCCounts();
00083   for(unsigned itime = 0; itime < theNumberOfSamples; ++itime) 
00084     {
00085       unsigned channel = (digi.getStrip()-1) % 16 + 1;
00086       unsigned value = scaCounts[itime] & 0xFFF; // 12-bit
00087       // assume it's good, since we're working with simulation
00088       const CSCCFEBTimeSlice * slice = timeSlice(itime);
00089       assert(slice != 0);
00090       slice->timeSample(layer, channel)->adcCounts = value;
00092       ((CSCCFEBTimeSlice *)slice)->setCRC();
00093     }
00094 }
00095 
00096 const CSCCFEBTimeSlice * CSCCFEBData::timeSlice(unsigned i) const 
00097 {
00098   const CSCCFEBTimeSlice * result;
00099   assert(i < theNumberOfSamples);
00100   std::pair<int,bool> start = theSliceStarts[i];
00101   // give a NULL pointer if this is a bad slice
00102   if(!start.second) 
00103     {
00104       result = 0;
00105     } 
00106   else 
00107     {
00108       result = reinterpret_cast<const CSCCFEBTimeSlice *>(theData+start.first);
00109     }
00110   return result;
00111 }
00112 
00113 
00114 unsigned CSCCFEBData::adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const 
00115 {
00116   unsigned result = 0;
00117   const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00118   // zero is returned for bad slices
00119   if(slice) result = slice->timeSample(layer, channel)->adcCounts;
00120   return result;
00121 }
00122 unsigned CSCCFEBData::adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const 
00123 {
00124   unsigned result = 0;
00125   const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00126   // zero is returned for bad slices
00127   if(slice) result = slice->timeSample(layer, channel)->adcOverflow;
00128   return result;
00129 }
00130 
00131 unsigned CSCCFEBData::controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const 
00132 {
00133 
00134 // The argument notation is
00135 // uglay = un-Gray Coded layer index 1-6
00136 // ugchan = un-Gray Coded channel index 1-16
00137 // The point being that the SCAC is serially encoded directly in the data stream (without Gray Coding)
00138 // so the layer and channel indexes here are just the direct ordering into the data stream.
00139 
00140   unsigned result = 0;
00141   const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00142   // zero is returned for bad slices
00143   if(slice) result = slice->timeSample( (ugchan-1)*6+uglay-1 )->controllerData;
00144   return result;
00145 }
00146 
00147 unsigned CSCCFEBData::overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const 
00148 {
00149   unsigned result = 0;
00150   const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00151   // zero is returned for bad slices
00152   if(slice) result = slice->timeSample(layer, channel)->overlappedSampleFlag;
00153   return result;
00154 }
00155 unsigned CSCCFEBData::errorstat(unsigned layer, unsigned channel, unsigned timeBin) const 
00156 {
00157   unsigned result = 0;
00158   const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00159   // zero is returned for bad slices
00160   if(slice) result = slice->timeSample(layer, channel)->errorstat;
00161   return result;
00162 }
00163 
00164 
00165 CSCCFEBStatusDigi CSCCFEBData::statusDigi() const 
00166 {
00170 
00171   std::vector<uint16_t> crcWords(nTimeSamples());
00172   std::vector<uint16_t> contrWords(nTimeSamples());
00173 
00174   if (nTimeSamples()==0) 
00175     {
00176       LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
00177     }
00178   else
00179     {
00180       for(unsigned itime = 0; itime < nTimeSamples(); ++itime) {
00181         const CSCCFEBTimeSlice * slice = timeSlice(itime);
00182         // zero is returned for bad slices
00183         if (slice) crcWords[itime] = slice->get_crc();
00184         if (slice) 
00185           {     
00186             int layer=1; 
00187             for(unsigned i = 0; i < 16; ++i)
00188               {
00189                 contrWords[itime] |= slice->timeSample(i*6+layer-1)->controllerData << i;
00190               }
00191           }
00192 
00193       }
00194     }
00195 
00196   CSCCFEBStatusDigi result(boardNumber_+1, crcWords, contrWords, bWords);
00197   return result;
00198 }
00199 
00200 
00201 
00202 void CSCCFEBData::digis(uint32_t idlayer, std::vector<CSCStripDigi> & result )
00203 {
00204   
00205   // assert(layer>0 && layer <= 6);
00206 
00207   LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
00208   if (nTimeSamples()==0) {
00209      LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
00210      return;
00211   }
00212 
00213   result.reserve(16);
00214 
00215   std::vector<int> sca(nTimeSamples());
00216   std::vector<uint16_t> overflow(nTimeSamples());
00217   std::vector<uint16_t> overlap(nTimeSamples());
00218   std::vector<uint16_t> errorfl(nTimeSamples());
00219 
00220   bool me1a = (CSCDetId::station(idlayer)==1) && (CSCDetId::ring(idlayer)==4);
00221   bool zplus = (CSCDetId::endcap(idlayer) == 1); 
00222   bool me1b = (CSCDetId::station(idlayer)==1) && (CSCDetId::ring(idlayer)==1);
00223   
00224   unsigned layer = CSCDetId::layer(idlayer);
00225 
00226   std::vector<uint16_t> l1a_phase(nTimeSamples());
00227   for(unsigned itime = 0; itime < nTimeSamples(); ++itime) {
00228     l1a_phase[itime] = controllerData(layer, 13, itime); // will be zero if timeslice bad
00229     LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " l1a_phase = " << controllerData(layer, 13, itime);
00230     LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " lct_phase = " << controllerData(layer, 14, itime);
00231     LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " # samples = " << controllerData(layer, 16, itime);
00232   };
00233 
00234   for(unsigned ichannel = 1; ichannel <= 16; ++ichannel)
00235     {
00236       // What is the point of testing here? Move it outside this loop
00237       //      if (nTimeSamples()==0)
00238       //        {
00239       //          LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
00240       //          break;
00241       //        }
00242       
00243       for(unsigned itime = 0; itime < nTimeSamples(); ++itime)
00244         {
00245           const CSCCFEBTimeSlice * slice = timeSlice(itime);
00246           if (slice)
00247             {
00248               CSCCFEBDataWord * word;
00249               word = slice->timeSample(layer, ichannel);
00250               if (word)
00251                 {  
00252                   sca[itime] = word->adcCounts;
00253                   overflow[itime] = word->adcOverflow;
00254                   overlap[itime] = word->overlappedSampleFlag;
00255                   errorfl[itime] = word->errorstat;
00256 
00257                   // Stick the l1a_phase bit into 'overlap' too (so we can store it in CSCStripDigi
00258                   // without changing CSCStripDigi format). 
00259                   // Put it in the 9th bit of the overlap word which is only 1-bit anyway.
00260                   overlap[itime] = (( l1a_phase[itime] & 0x1 ) << 8 ) | ( word->overlappedSampleFlag & 0x1 );
00261                 }
00262             }
00263         }
00264       if (sca.empty())
00265         {
00266           LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
00267           break;
00268         }
00269       int strip = ichannel + 16*boardNumber_;
00270       if ( me1a ) strip = strip%64; // reset 65-80 to 1-16 digi
00271       if ( me1a && zplus ) { strip = 17-strip; } // 1-16 -> 16-1 
00272       if ( me1b && !zplus) { strip = 65 - strip;} // 1-64 -> 64-1 ...
00273       result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
00274     } 
00275 }
00276 
00277 
00278 
00279 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer)
00280 {
00281   //assert(layer>0 && layer <= 6);
00282   std::vector<CSCStripDigi> result;
00283   uint32_t layer= idlayer;
00284   digis(layer, result);
00285   return result;
00286 }
00287 
00288 
00289 
00290 bool CSCCFEBData::check() const 
00291 {
00292   bool result = true;
00293   for(unsigned i = 0; i < theNumberOfSamples; ++i) 
00294     {
00295       const CSCCFEBTimeSlice * slice = timeSlice(i);
00296       if(slice==0 || !timeSlice(i)->check()) result = false;
00297     }
00298   return result;
00299 }
00300 
00301 std::ostream & operator<<(std::ostream & os, const CSCCFEBData & data) 
00302 {
00303   os << "printing CFEB data sample by sample " << std::endl;
00304   for(unsigned ilayer = 1; ilayer <= 6; ++ilayer) 
00305     {
00306       for(unsigned channel = 1; channel <= 16; ++channel) 
00307         {
00308           unsigned strip = channel + data.boardNumber_*16;
00309           os << "Strip " << strip << " ";
00310           for(unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin)
00311             {
00312               os << data.adcCounts(ilayer, channel, timeBin) << " " ;
00313             }
00314           os << std::endl;
00315         }
00316     }
00317   return os;
00318 }
00319 
00320 std::vector < std::vector<CSCStripDigi> > CSCCFEBData::stripDigis()
00321 {
00322   std::vector < std::vector<CSCStripDigi> > result;
00323   for (int layer = 1; layer <= 6; ++layer) 
00324     {
00325       result.push_back(digis(layer));
00326     }
00327   return result;
00328 }
00329