Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:25

0001 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBData.h"
0002 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBTimeSlice.h"
0003 #include "EventFilter/CSCRawToDigi/interface/CSCBadCFEBTimeSlice.h"
0004 #include "DataFormats/CSCDigi/interface/CSCStripDigi.h"
0005 #include "DataFormats/CSCDigi/interface/CSCCFEBStatusDigi.h"
0006 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0007 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include <cassert>
0010 
0011 CSCCFEBData::CSCCFEBData(unsigned number, const uint16_t *buf, uint16_t format_version, bool f_dcfeb)
0012     : theSize(0), boardNumber_(number), theNumberOfSamples(0), theFormatVersion(format_version), fDCFEB(f_dcfeb) {
0013   // I may be grabbing too many words, but that's OK
0014   // parse for time slices
0015   unsigned pos = 0;
0016   // to be set later
0017   unsigned maxSamples = 8;
0018   theSliceStarts.reserve(8);
0019   while (theNumberOfSamples < maxSamples) {
0020     // first see if it's a bad slice
0021     const CSCBadCFEBTimeSlice *badSlice = reinterpret_cast<const CSCBadCFEBTimeSlice *>(buf + pos);
0022     if (badSlice->check()) {
0023       //show that a bad slice starts here
0024       theSliceStarts.push_back(std::pair<int, bool>(pos, false));
0025       pos += badSlice->sizeInWords();
0026       //store bad word for status digis
0027       bWords.push_back(badSlice->word(1).data());  //all 4 words are assumed identical so saving #1 only
0028     } else {
0029       // OK.  Maybe it's good.
0030       const CSCCFEBTimeSlice *goodSlice = reinterpret_cast<const CSCCFEBTimeSlice *>(buf + pos);
0031       if (goodSlice->check()) {
0032         // show that a good slice starts here
0033         theSliceStarts.push_back(std::pair<int, bool>(pos, true));
0034         // it will just be an array of CSCCFEBTimeSlices, so we'll
0035         // grab the number of time slices from the first good one
0036         // !!! VB - Limit maximum number of CFEB samples to 8.
0037         // !!!      In Run2 rare CFEB data corruptions were causing RECO problems with mistakenly setting 16 samples flags
0038         // !!!      Will need another fix in case of CSC switch to 16 samples readout
0039         // maxSamples =   goodSlice->sixteenSamples() ? 16 : 8;
0040         if (goodSlice->sixteenSamples())
0041           LogTrace("CSCCFEBData|CSCRawToDigi")
0042               << "CFEB DATA slice " << theNumberOfSamples << " 16 samples flag is detected";
0043         pos += goodSlice->sizeInWords();
0044       } else {
0045         LogTrace("CSCCFEBData|CSCRawToDigi")
0046             << "CORRUPT CFEB DATA slice " << theNumberOfSamples << std::hex << " " << *(buf + pos + 3) << " "
0047             << *(buf + pos + 2) << " " << *(buf + pos + 1) << " " << *(buf + pos);
0048         //ok slice is bad but try another one at 100 words after it
0049         theSliceStarts.push_back(std::pair<int, bool>(pos, false));
0050         pos += 100;
0051       }
0052     }
0053     ++theNumberOfSamples;
0054   }
0055   theSize = pos;
0056   memcpy(theData, buf, theSize * 2);
0057 }
0058 
0059 CSCCFEBData::CSCCFEBData(unsigned number, bool sixteenSamples, uint16_t format_version, bool f_dcfeb)
0060     : boardNumber_(number),
0061       theNumberOfSamples(sixteenSamples ? 16 : 8),
0062       theFormatVersion(format_version),
0063       fDCFEB(f_dcfeb) {
0064   theSliceStarts.reserve(theNumberOfSamples);
0065 
0066   // fill the SCA controller words
0067   CSCCFEBSCAControllerWord scaWord;
0068   scaWord.ts_flag = sixteenSamples;
0069 
0070   // make a template slice to copy into theData buffer
0071   CSCCFEBTimeSlice slice;
0072   slice.setControllerWord(scaWord);
0073 
0074   for (unsigned i = 0; i < theNumberOfSamples; ++i) {
0075     unsigned short *pos = theData + i * 100;
0076     memcpy(pos, &slice, 200);
0077     theSliceStarts.push_back(std::pair<int, bool>(i * 100, true));
0078   }
0079   theSize = theNumberOfSamples * 100;
0080 }
0081 
0082 void CSCCFEBData::add(const CSCStripDigi &digi, int layer) {
0083   std::vector<int> scaCounts = digi.getADCCounts();
0084   for (unsigned itime = 0; itime < theNumberOfSamples; ++itime) {
0085     unsigned channel = (digi.getStrip() - 1) % 16 + 1;
0086     unsigned value = scaCounts[itime] & 0xFFF;  // 12-bit
0087     // assume it's good, since we're working with simulation
0088     CSCCFEBTimeSlice *slice = timeSlice(itime);
0089     assert(slice != nullptr);
0090     slice->timeSample(layer, channel, fDCFEB)->adcCounts = value;
0091     /// =VB= Set CRC value for simulated data
0092     slice->setCRC();
0093   }
0094 }
0095 
0096 const CSCCFEBTimeSlice *CSCCFEBData::timeSlice(unsigned i) const {
0097   assert(i < theNumberOfSamples);
0098   std::pair<int, bool> start = theSliceStarts[i];
0099   // give a NULL pointer if this is a bad slice
0100   return start.second ? reinterpret_cast<const CSCCFEBTimeSlice *>(theData + start.first) : nullptr;
0101 }
0102 
0103 CSCCFEBTimeSlice *CSCCFEBData::timeSlice(unsigned i) {
0104   assert(i < theNumberOfSamples);
0105   std::pair<int, bool> start = theSliceStarts[i];
0106   // give a NULL pointer if this is a bad slice
0107   return start.second ? reinterpret_cast<CSCCFEBTimeSlice *>(theData + start.first) : nullptr;
0108 }
0109 
0110 unsigned CSCCFEBData::adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const {
0111   unsigned result = 0;
0112   const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0113   // zero is returned for bad slices
0114   if (slice)
0115     result = slice->timeSample(layer, channel, fDCFEB)->adcCounts;
0116   return result;
0117 }
0118 unsigned CSCCFEBData::adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const {
0119   unsigned result = 0;
0120   const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0121   // zero is returned for bad slices
0122   if (slice)
0123     result = slice->timeSample(layer, channel, fDCFEB)->adcOverflow;
0124   return result;
0125 }
0126 
0127 unsigned CSCCFEBData::controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const {
0128   // The argument notation is
0129   // uglay = un-Gray Coded layer index 1-6
0130   // ugchan = un-Gray Coded channel index 1-16
0131   // The point being that the SCAC is serially encoded directly in the data stream (without Gray Coding)
0132   // so the layer and channel indexes here are just the direct ordering into the data stream.
0133 
0134   unsigned result = 0;
0135   const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0136   // zero is returned for bad slices
0137   if (slice)
0138     result = slice->timeSample((ugchan - 1) * 6 + uglay - 1)->controllerData;
0139   return result;
0140 }
0141 
0142 unsigned CSCCFEBData::overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const {
0143   unsigned result = 0;
0144   const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0145   // zero is returned for bad slices
0146   if (slice)
0147     result = slice->timeSample(layer, channel, fDCFEB)->overlappedSampleFlag;
0148   return result;
0149 }
0150 unsigned CSCCFEBData::errorstat(unsigned layer, unsigned channel, unsigned timeBin) const {
0151   unsigned result = 0;
0152   const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0153   // zero is returned for bad slices
0154   if (slice)
0155     result = slice->timeSample(layer, channel, fDCFEB)->errorstat;
0156   return result;
0157 }
0158 
0159 void CSCCFEBData::setL1A(unsigned l1a) {
0160   for (unsigned i = 0; i < theNumberOfSamples; i++)
0161     setL1A(i, l1a);
0162 }
0163 
0164 void CSCCFEBData::setL1A(unsigned i, unsigned l1a) {
0165   assert(i < theNumberOfSamples);
0166   std::pair<int, bool> start = theSliceStarts[i];
0167   // give a NULL pointer if this is a bad slice
0168   if (start.second) {
0169     (reinterpret_cast<CSCCFEBTimeSlice *>(theData + start.first))->set_L1Anumber(l1a);
0170   }
0171 }
0172 
0173 CSCCFEBStatusDigi CSCCFEBData::statusDigi() const {
0174   ///returns one status digi per cfeb
0175   ///contains bWord if slice is bad
0176   ///also contains crc word and controller word
0177 
0178   std::vector<uint16_t> crcWords(nTimeSamples());
0179   std::vector<uint16_t> contrWords(nTimeSamples());
0180 
0181   if (nTimeSamples() == 0) {
0182     LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
0183   } else {
0184     for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
0185       const CSCCFEBTimeSlice *slice = timeSlice(itime);
0186       // zero is returned for bad slices
0187       if (slice)
0188         crcWords[itime] = slice->get_crc();
0189       if (slice) {
0190         int layer = 1;  ///here layer=1 bec this word repeats 6 times for each layer
0191         for (unsigned i = 0; i < 16; ++i) {
0192           contrWords[itime] |= slice->timeSample(i * 6 + layer - 1)->controllerData << i;
0193         }
0194       }
0195     }
0196   }
0197 
0198   CSCCFEBStatusDigi result(boardNumber_ + 1, crcWords, contrWords, bWords);
0199   return result;
0200 }
0201 
0202 void CSCCFEBData::digis(uint32_t idlayer, std::vector<CSCStripDigi> &result) const {
0203   LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
0204   if (nTimeSamples() == 0) {
0205     LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
0206     return;
0207   }
0208 
0209   result.reserve(16);
0210 
0211   std::vector<int> sca(nTimeSamples());
0212   std::vector<uint16_t> overflow(nTimeSamples());
0213   std::vector<uint16_t> overlap(nTimeSamples());
0214   std::vector<uint16_t> errorfl(nTimeSamples());
0215 
0216   bool me1a = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 4);
0217   bool zplus = (CSCDetId::endcap(idlayer) == 1);
0218   bool me1b = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 1);
0219 
0220   unsigned layer = CSCDetId::layer(idlayer);
0221 
0222   std::vector<uint16_t> l1a_phase(nTimeSamples());
0223   for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
0224     l1a_phase[itime] = controllerData(layer, 13, itime);  // will be zero if timeslice bad
0225     LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
0226                                          << " l1a_phase = " << controllerData(layer, 13, itime);
0227     LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
0228                                          << " lct_phase = " << controllerData(layer, 14, itime);
0229     LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
0230                                          << " # samples = " << controllerData(layer, 16, itime);
0231   };
0232 
0233   for (unsigned ichannel = 1; ichannel <= 16; ++ichannel) {
0234     // What is the point of testing here? Move it outside this loop
0235     //      if (nTimeSamples()==0)
0236     //  {
0237     //    LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
0238     //    break;
0239     //  }
0240 
0241     for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
0242       const CSCCFEBTimeSlice *slice = timeSlice(itime);
0243       if (slice) {
0244         CSCCFEBDataWord *word;
0245         word = slice->timeSample(layer, ichannel, fDCFEB);
0246         if (word) {  ///for bad or missing data word will be zero
0247           sca[itime] = word->adcCounts;
0248           overflow[itime] = word->adcOverflow;
0249           overlap[itime] = word->overlappedSampleFlag;
0250           errorfl[itime] = word->errorstat;
0251 
0252           // Stick the l1a_phase bit into 'overlap' too (so we can store it in CSCStripDigi
0253           // without changing CSCStripDigi format).
0254           // Put it in the 9th bit of the overlap word which is only 1-bit anyway.
0255           overlap[itime] = ((l1a_phase[itime] & 0x1) << 8) | (word->overlappedSampleFlag & 0x1);
0256         }
0257       }
0258     }
0259     if (sca.empty()) {
0260       LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
0261       break;
0262     }
0263     int strip = ichannel + 16 * boardNumber_;
0264 
0265     if (theFormatVersion >= 2013) {  /// Handle 2013 Format
0266 
0267       if (me1a)
0268         strip = strip % CSCConstants::NUM_STRIPS_ME1B;  // reset 65-112/ to 1-48 digi
0269       if (me1a && zplus) {
0270         strip = CSCConstants::NUM_STRIPS_ME1A_UNGANGED + 1 - strip;
0271       }  // 1-48 -> 48-1
0272       if (me1b && !zplus) {
0273         strip = CSCConstants::NUM_STRIPS_ME1B + 1 - strip;
0274       }  // 1-64 -> 64-1 ...
0275 
0276     } else {  // Handle original 2005 format
0277 
0278       if (me1a)
0279         strip = strip % CSCConstants::NUM_STRIPS_ME1B;  // reset 65-80 to 1-16 digi
0280       if (me1a && zplus) {
0281         strip = CSCConstants::NUM_STRIPS_ME1A_GANGED + 1 - strip;
0282       }  // 1-16 -> 16-1
0283       if (me1b && !zplus) {
0284         strip = CSCConstants::NUM_STRIPS_ME1B + 1 - strip;
0285       }  // 1-64 -> 64-1 ...
0286     }
0287     result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
0288   }
0289 }
0290 
0291 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer) const {
0292   std::vector<CSCStripDigi> result;
0293   uint32_t layer = idlayer;
0294   digis(layer, result);
0295   return result;
0296 }
0297 
0298 bool CSCCFEBData::check() const {
0299   bool result = true;
0300   for (unsigned i = 0; i < theNumberOfSamples; ++i) {
0301     const CSCCFEBTimeSlice *slice = timeSlice(i);
0302     if (slice == nullptr || !timeSlice(i)->check())
0303       result = false;
0304   }
0305   return result;
0306 }
0307 
0308 std::ostream &operator<<(std::ostream &os, const CSCCFEBData &data) {
0309   os << "printing CFEB data sample by sample " << std::endl;
0310   for (int ilayer = CSCDetId::minLayerId(); ilayer <= CSCDetId::maxLayerId(); ++ilayer) {
0311     for (unsigned channel = 1; channel <= 16; ++channel) {
0312       unsigned strip = channel + data.boardNumber_ * 16;
0313       os << "Strip " << strip << " ";
0314       for (unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin) {
0315         os << data.adcCounts(ilayer, channel, timeBin) << " ";
0316       }
0317       os << std::endl;
0318     }
0319   }
0320   return os;
0321 }
0322 
0323 std::vector<std::vector<CSCStripDigi> > CSCCFEBData::stripDigis() {
0324   std::vector<std::vector<CSCStripDigi> > result;
0325   for (int layer = CSCDetId::minLayerId(); layer <= CSCDetId::maxLayerId(); ++layer) {
0326     result.push_back(digis(layer));
0327   }
0328   return result;
0329 }