Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:16

0001 #include "EventFilter/SiPixelRawToDigi/interface/PixelDataFormatter.h"
0002 
0003 #include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingTree.h"
0004 #include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingMap.h"
0005 #include "CondFormats/SiPixelObjects/interface/SiPixelFrameConverter.h"
0006 
0007 #include "CondFormats/SiPixelObjects/interface/SiPixelQuality.h"
0008 
0009 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0010 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0011 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0012 
0013 #include "CondFormats/SiPixelObjects/interface/PixelROC.h"
0014 #include "DataFormats/TrackerCommon/interface/PixelBarrelName.h"
0015 
0016 #include "FWCore/Utilities/interface/Exception.h"
0017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0018 
0019 #include <bitset>
0020 #include <sstream>
0021 #include <iostream>
0022 
0023 using namespace std;
0024 using namespace edm;
0025 using namespace sipixelobjects;
0026 using namespace sipixelconstants;
0027 
0028 PixelDataFormatter::PixelDataFormatter(const SiPixelFedCablingTree* map, bool phase)
0029     : theDigiCounter_(0),
0030       theWordCounter_(0),
0031       theCablingTree_(map),
0032       badPixelInfo_(nullptr),
0033       modulesToUnpack_(nullptr),
0034       phase1_(phase) {
0035   int s32 = sizeof(Word32);
0036   int s64 = sizeof(Word64);
0037   int s8 = sizeof(char);
0038   if (s8 != 1 || s32 != 4 * s8 || s64 != 2 * s32) {
0039     LogError("UnexpectedSizes") << " unexpected sizes: "
0040                                 << "  size of char is: " << s8 << ", size of Word32 is: " << s32
0041                                 << ", size of Word64 is: " << s64 << ", send exception";
0042   }
0043   includeErrors_ = false;
0044   useQualityInfo_ = false;
0045   allDetDigis_ = 0;
0046   hasDetDigis_ = 0;
0047 
0048   if (phase1_) {
0049     maxROCIndex_ = 8;
0050     errorcheck_ = std::unique_ptr<ErrorCheckerBase>(new ErrorChecker());
0051   } else {
0052     maxROCIndex_ = 25;
0053     errorcheck_ = std::unique_ptr<ErrorCheckerBase>(new ErrorCheckerPhase0());
0054   }
0055 }
0056 
0057 void PixelDataFormatter::setErrorStatus(bool ErrorStatus) {
0058   includeErrors_ = ErrorStatus;
0059   errorcheck_->setErrorStatus(includeErrors_);
0060 }
0061 
0062 void PixelDataFormatter::setQualityStatus(bool QualityStatus, const SiPixelQuality* QualityInfo) {
0063   useQualityInfo_ = QualityStatus;
0064   badPixelInfo_ = QualityInfo;
0065 }
0066 
0067 void PixelDataFormatter::setModulesToUnpack(const std::set<unsigned int>* moduleIds) { modulesToUnpack_ = moduleIds; }
0068 
0069 void PixelDataFormatter::passFrameReverter(const SiPixelFrameReverter* reverter) { theFrameReverter_ = reverter; }
0070 
0071 void PixelDataFormatter::interpretRawData(
0072     bool& errorsInEvent, int fedId, const FEDRawData& rawData, Collection& digis, Errors& errors) {
0073   using namespace sipixelobjects;
0074 
0075   int nWords = rawData.size() / sizeof(Word64);
0076   if (nWords == 0)
0077     return;
0078 
0079   SiPixelFrameConverter converter(theCablingTree_, fedId);
0080 
0081   // check CRC bit
0082   const Word64* trailer = reinterpret_cast<const Word64*>(rawData.data()) + (nWords - 1);
0083   if (!errorcheck_->checkCRC(errorsInEvent, fedId, trailer, errors))
0084     return;
0085 
0086   // check headers
0087   const Word64* header = reinterpret_cast<const Word64*>(rawData.data());
0088   header--;
0089   bool moreHeaders = true;
0090   while (moreHeaders) {
0091     header++;
0092     LogTrace("") << "HEADER:  " << print(*header);
0093     bool headerStatus = errorcheck_->checkHeader(errorsInEvent, fedId, header, errors);
0094     moreHeaders = headerStatus;
0095   }
0096 
0097   // check trailers
0098   bool moreTrailers = true;
0099   trailer++;
0100   while (moreTrailers) {
0101     trailer--;
0102     LogTrace("") << "TRAILER: " << print(*trailer);
0103     bool trailerStatus = errorcheck_->checkTrailer(errorsInEvent, fedId, nWords, trailer, errors);
0104     moreTrailers = trailerStatus;
0105   }
0106 
0107   // data words
0108   theWordCounter_ += 2 * (nWords - 2);
0109   LogTrace("") << "data words: " << (trailer - header - 1);
0110 
0111   int link = -1;
0112   int roc = -1;
0113   int layer = 0;
0114   unsigned int rawId = 0;
0115   unsigned int nrawId = 0;
0116   PixelROC const* rocp = nullptr;
0117   bool skipROC = false;
0118   edm::DetSet<PixelDigi>* detDigis = nullptr;
0119 
0120   const Word32* bw = (const Word32*)(header + 1);
0121   const Word32* ew = (const Word32*)(trailer);
0122   if (*(ew - 1) == 0) {
0123     ew--;
0124     theWordCounter_--;
0125   }
0126   for (auto word = bw; word < ew; ++word) {
0127     LogTrace("") << "DATA: " << print(*word);
0128 
0129     auto ww = *word;
0130     if UNLIKELY (ww == 0) {
0131       theWordCounter_--;
0132       continue;
0133     }
0134     int nlink = getLink(ww);
0135     int nroc = getROC(ww);
0136 
0137     if ((nlink != link) | (nroc != roc)) {  // new roc
0138       link = nlink;
0139       roc = nroc;
0140       skipROC = LIKELY(roc < maxROCIndex_)
0141                     ? false
0142                     : !errorcheck_->checkROC(errorsInEvent, fedId, &converter, theCablingTree_, ww, errors);
0143       if (skipROC)
0144         continue;
0145       rocp = converter.toRoc(link, roc);
0146       if UNLIKELY (!rocp) {
0147         errorsInEvent = true;
0148         errorcheck_->conversionError(fedId, &converter, 2, ww, errors);
0149         skipROC = true;
0150         continue;
0151       }
0152       rawId = rocp->rawId();
0153       bool barrel = PixelModuleName::isBarrel(rawId);
0154       if (barrel)
0155         layer = PixelROC::bpixLayerPhase1(rawId);
0156       else
0157         layer = 0;
0158 
0159       if (useQualityInfo_ & (nullptr != badPixelInfo_)) {
0160         short rocInDet = (short)rocp->idInDetUnit();
0161         skipROC = badPixelInfo_->IsRocBad(rawId, rocInDet);
0162         if (skipROC)
0163           continue;
0164       }
0165       skipROC = modulesToUnpack_ && (modulesToUnpack_->find(rawId) == modulesToUnpack_->end());
0166       if (skipROC)
0167         continue;
0168     }
0169 
0170     // skip is roc to be skipped ot invalid
0171     if UNLIKELY (skipROC || !rocp)
0172       continue;
0173 
0174     int adc = getADC(ww);
0175     std::unique_ptr<LocalPixel> local;
0176 
0177     if (phase1_ && layer == 1) {  // special case for layer 1ROC
0178       // for l1 roc use the roc column and row index instead of dcol and pixel index.
0179       int col = getCol(ww);
0180       int row = getRow(ww);
0181 
0182       LocalPixel::RocRowCol localCR = {row, col};  // build pixel
0183       if UNLIKELY (!localCR.valid()) {
0184         LogDebug("PixelDataFormatter::interpretRawData") << "status #3";
0185         errorsInEvent = true;
0186         errorcheck_->conversionError(fedId, &converter, 3, ww, errors);
0187         continue;
0188       }
0189       local = std::make_unique<LocalPixel>(localCR);  // local pixel coordinate
0190 
0191     } else {  // phase0 and phase1 except bpix layer 1
0192       int dcol = getDCol(ww);
0193       int pxid = getPxId(ww);
0194       LocalPixel::DcolPxid localDP = {dcol, pxid};
0195 
0196       if UNLIKELY (!localDP.valid()) {
0197         LogDebug("PixelDataFormatter::interpretRawData") << "status #3";
0198         errorsInEvent = true;
0199         errorcheck_->conversionError(fedId, &converter, 3, ww, errors);
0200         continue;
0201       }
0202       local = std::make_unique<LocalPixel>(localDP);  // local pixel coordinate
0203     }
0204 
0205     if (nrawId != rawId) {
0206       nrawId = rawId;
0207       detDigis = &digis.find_or_insert(rawId);
0208       if ((*detDigis).empty()) {
0209         (*detDigis).data.reserve(32);  // avoid the first relocations
0210       }
0211     }
0212 
0213     if (detDigis) {
0214       GlobalPixel global = rocp->toGlobal(*local);  // global pixel coordinate (in module)
0215       (*detDigis).data.emplace_back(global.row, global.col, adc);
0216       LogTrace("") << (*detDigis).data.back();
0217     } else {
0218       LogError("NullPointerException") << "@SUB=PixelDataFormatter::interpretRawData"
0219                                        << "DetSet pointer not set. This is not supposed to happen.";
0220     }
0221   }
0222 }
0223 
0224 void PixelDataFormatter::formatRawData(unsigned int lvl1_ID,
0225                                        RawData& fedRawData,
0226                                        const Digis& digis,
0227                                        const BadChannels& badChannels) {
0228   std::map<int, vector<Word32> > words;
0229 
0230   // translate digis into 32-bit raw words and store in map indexed by Fed
0231   for (Digis::const_iterator im = digis.begin(); im != digis.end(); im++) {
0232     allDetDigis_++;
0233     cms_uint32_t rawId = im->first;
0234     int layer = 0;
0235     bool barrel = PixelModuleName::isBarrel(rawId);
0236     if (barrel)
0237       layer = PixelROC::bpixLayerPhase1(rawId);
0238 
0239     BadChannels::const_iterator detBadChannels = badChannels.find(rawId);
0240 
0241     hasDetDigis_++;
0242     const DetDigis& detDigis = im->second;
0243     for (DetDigis::const_iterator it = detDigis.begin(); it != detDigis.end(); it++) {
0244       theDigiCounter_++;
0245       const PixelDigi& digi = (*it);
0246       int fedId = 0;
0247 
0248       if (layer == 1 && phase1_)
0249         fedId = digi2wordPhase1Layer1(rawId, digi, words);
0250       else
0251         fedId = digi2word(rawId, digi, words);
0252 
0253       if (fedId < 0) {
0254         LogError("FormatDataException") << " digi2word returns error #" << fedId << " Ndigis: " << theDigiCounter_
0255                                         << endl
0256                                         << " detector: " << rawId << endl
0257                                         << print(digi) << endl;
0258       } else if (detBadChannels != badChannels.end()) {
0259         auto badChannel =
0260             std::find_if(detBadChannels->second.begin(), detBadChannels->second.end(), [&](const PixelFEDChannel& ch) {
0261               return (int(ch.fed) == fedId && ch.link == getLink(words[fedId].back()));
0262             });
0263         if (badChannel != detBadChannels->second.end()) {
0264           LogError("FormatDataException") << " while marked bad, found digi for FED " << fedId << " Link "
0265                                           << getLink(words[fedId].back()) << " on module " << rawId << endl
0266                                           << print(digi) << endl;
0267         }
0268       }  // if (fedId)
0269     }  // for (DetDigis
0270   }  // for (Digis
0271   LogTrace(" allDetDigis_/hasDetDigis_ : ") << allDetDigis_ << "/" << hasDetDigis_;
0272 
0273   // fill FED error 25 words
0274   for (const auto& detBadChannels : badChannels) {
0275     for (const auto& badChannel : detBadChannels.second) {
0276       unsigned int FEDError25 = 25;
0277       Word32 word = (badChannel.link << LINK_shift) | (FEDError25 << ROC_shift);
0278       words[badChannel.fed].push_back(word);
0279       theWordCounter_++;
0280     }
0281   }
0282 
0283   typedef std::map<int, vector<Word32> >::const_iterator RI;
0284   for (RI feddata = words.begin(); feddata != words.end(); feddata++) {
0285     int fedId = feddata->first;
0286     // since raw words are written in the form of 64-bit packets
0287     // add extra 32-bit word to make number of words even if necessary
0288     if (words.find(fedId)->second.size() % 2 != 0)
0289       words[fedId].push_back(Word32(0));
0290 
0291     // size in Bytes; create output structure
0292     int dataSize = words.find(fedId)->second.size() * sizeof(Word32);
0293     int nHeaders = 1;
0294     int nTrailers = 1;
0295     dataSize += (nHeaders + nTrailers) * sizeof(Word64);
0296     FEDRawData* rawData = new FEDRawData(dataSize);
0297 
0298     // get begining of data;
0299     Word64* word = reinterpret_cast<Word64*>(rawData->data());
0300 
0301     // write one header
0302     FEDHeader::set(reinterpret_cast<unsigned char*>(word), 0, lvl1_ID, 0, fedId);
0303     word++;
0304 
0305     // write data
0306     unsigned int nWord32InFed = words.find(fedId)->second.size();
0307     for (unsigned int i = 0; i < nWord32InFed; i += 2) {
0308       *word = (Word64(words.find(fedId)->second[i + 1]) << 32) | words.find(fedId)->second[i];
0309       LogDebug("PixelDataFormatter") << print(*word);
0310       word++;
0311     }
0312 
0313     // write one trailer
0314     FEDTrailer::set(reinterpret_cast<unsigned char*>(word), dataSize / sizeof(Word64), 0, 0, 0);
0315     word++;
0316 
0317     // check memory
0318     if (word != reinterpret_cast<Word64*>(rawData->data() + dataSize)) {
0319       string s = "** PROBLEM in PixelDataFormatter !!!";
0320       throw cms::Exception(s);
0321     }  // if (word !=
0322     fedRawData[fedId] = *rawData;
0323     delete rawData;
0324   }  // for (RI feddata
0325 }
0326 
0327 int PixelDataFormatter::digi2word(cms_uint32_t detId,
0328                                   const PixelDigi& digi,
0329                                   std::map<int, vector<Word32> >& words) const {
0330   LogDebug("PixelDataFormatter") << print(digi);
0331 
0332   DetectorIndex detector = {detId, digi.row(), digi.column()};
0333   ElectronicIndex cabling;
0334   int fedId = theFrameReverter_->toCabling(cabling, detector);
0335   if (fedId < 0)
0336     return fedId;
0337 
0338   Word32 word = (cabling.link << LINK_shift) | (cabling.roc << ROC_shift) | (cabling.dcol << DCOL_shift) |
0339                 (cabling.pxid << PXID_shift) | (digi.adc() << ADC_shift);
0340   words[fedId].push_back(word);
0341   theWordCounter_++;
0342 
0343   return fedId;
0344 }
0345 int PixelDataFormatter::digi2wordPhase1Layer1(cms_uint32_t detId,
0346                                               const PixelDigi& digi,
0347                                               std::map<int, vector<Word32> >& words) const {
0348   LogDebug("PixelDataFormatter") << print(digi);
0349 
0350   DetectorIndex detector = {detId, digi.row(), digi.column()};
0351   ElectronicIndex cabling;
0352   int fedId = theFrameReverter_->toCabling(cabling, detector);
0353   if (fedId < 0)
0354     return fedId;
0355 
0356   int col = ((cabling.dcol) * 2) + ((cabling.pxid) % 2);
0357   int row = LocalPixel::numRowsInRoc - ((cabling.pxid) / 2);
0358 
0359   Word32 word = (cabling.link << LINK_shift) | (cabling.roc << ROC_shift) | (col << COL_shift) | (row << ROW_shift) |
0360                 (digi.adc() << ADC_shift);
0361   words[fedId].push_back(word);
0362   theWordCounter_++;
0363 
0364   return fedId;
0365 }
0366 
0367 std::string PixelDataFormatter::print(const PixelDigi& digi) const {
0368   ostringstream str;
0369   str << " DIGI: row: " << digi.row() << ", col: " << digi.column() << ", adc: " << digi.adc();
0370   return str.str();
0371 }
0372 
0373 std::string PixelDataFormatter::print(const Word64& word) const {
0374   ostringstream str;
0375   str << "word64:  " << reinterpret_cast<const bitset<64>&>(word);
0376   return str.str();
0377 }
0378 
0379 void PixelDataFormatter::unpackFEDErrors(PixelDataFormatter::Errors const& errors,
0380                                          std::vector<int> const& tkerrorlist,
0381                                          std::vector<int> const& usererrorlist,
0382                                          edm::DetSetVector<SiPixelRawDataError>& errorcollection,
0383                                          DetIdCollection& tkerror_detidcollection,
0384                                          DetIdCollection& usererror_detidcollection,
0385                                          edmNew::DetSetVector<PixelFEDChannel>& disabled_channelcollection,
0386                                          DetErrors& nodeterrors) {
0387   const uint32_t dummyDetId = 0xffffffff;
0388   for (const auto& [errorDetId, rawErrorsVec] : errors) {
0389     if (errorDetId == dummyDetId) {  // errors given dummy detId must be sorted by Fed
0390       nodeterrors.insert(nodeterrors.end(), rawErrorsVec.begin(), rawErrorsVec.end());
0391     } else {
0392       edm::DetSet<SiPixelRawDataError>& errorDetSet = errorcollection.find_or_insert(errorDetId);
0393       errorDetSet.data.insert(errorDetSet.data.end(), rawErrorsVec.begin(), rawErrorsVec.end());
0394       // Fill detid of the detectors where there is error AND the error number is listed
0395       // in the configurable error list in the job option cfi.
0396       // Code needs to be here, because there can be a set of errors for each
0397       // entry in the for loop over PixelDataFormatter::Errors
0398 
0399       std::vector<PixelFEDChannel> disabledChannelsDetSet;
0400 
0401       for (auto const& aPixelError : errorDetSet) {
0402         // For the time being, we extend the error handling functionality with ErrorType 25
0403         // In the future, we should sort out how the usage of tkerrorlist can be generalized
0404         if (phase1_ && aPixelError.getType() == 25) {
0405           int fedId = aPixelError.getFedId();
0406           const sipixelobjects::PixelFEDCabling* fed = theCablingTree_->fed(fedId);
0407           if (fed) {
0408             cms_uint32_t linkId = getLink(aPixelError.getWord32());
0409             const sipixelobjects::PixelFEDLink* link = fed->link(linkId);
0410             if (link) {
0411               // The "offline" 0..15 numbering is fixed by definition, also, the FrameConversion depends on it
0412               // in contrast, the ROC-in-channel numbering is determined by hardware --> better to use the "offline" scheme
0413               PixelFEDChannel ch = {fed->id(), linkId, 25, 0};
0414               for (unsigned int iRoc = 1; iRoc <= link->numberOfROCs(); iRoc++) {
0415                 const sipixelobjects::PixelROC* roc = link->roc(iRoc);
0416                 if (roc->idInDetUnit() < ch.roc_first)
0417                   ch.roc_first = roc->idInDetUnit();
0418                 if (roc->idInDetUnit() > ch.roc_last)
0419                   ch.roc_last = roc->idInDetUnit();
0420               }
0421               disabledChannelsDetSet.push_back(ch);
0422             }
0423           }
0424         } else {
0425           // fill list of detIds to be turned off by tracking
0426           if (!tkerrorlist.empty()) {
0427             auto it_find = std::find(tkerrorlist.begin(), tkerrorlist.end(), aPixelError.getType());
0428             if (it_find != tkerrorlist.end()) {
0429               tkerror_detidcollection.push_back(errorDetId);
0430             }
0431           }
0432         }
0433 
0434         // fill list of detIds with errors to be studied
0435         if (!usererrorlist.empty()) {
0436           auto it_find = std::find(usererrorlist.begin(), usererrorlist.end(), aPixelError.getType());
0437           if (it_find != usererrorlist.end()) {
0438             usererror_detidcollection.push_back(errorDetId);
0439           }
0440         }
0441 
0442       }  // loop on DetSet of errors
0443 
0444       if (!disabledChannelsDetSet.empty()) {
0445         disabled_channelcollection.insert(errorDetId, disabledChannelsDetSet.data(), disabledChannelsDetSet.size());
0446       }
0447 
0448     }  // if error assigned to a real DetId
0449   }  // loop on errors in event for this FED
0450 }