Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:00:22

0001 #include <iomanip>
0002 #include <iostream>
0003 #include <sstream>
0004 
0005 #include <fmt/format.h>
0006 
0007 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0008 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0009 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0010 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0011 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
0012 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
0013 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0014 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/Utilities/interface/CRC16.h"
0017 
0018 #include "SiStripDigiToRaw.h"
0019 
0020 namespace sistrip {
0021 
0022   // -----------------------------------------------------------------------------
0023   /** */
0024   DigiToRaw::DigiToRaw(FEDReadoutMode mode, uint8_t packetCode, bool useFedKey)
0025       : mode_(mode),
0026         packetCode_(packetCode),
0027         useFedKey_(useFedKey),
0028         bufferGenerator_(),
0029         warnings_("DigiToRaw", "[sistrip::DigiToRaw::createFedBuffers_]", edm::isDebugEnabled()) {
0030     if (edm::isDebugEnabled()) {
0031       LogDebug("DigiToRaw") << "[sistrip::DigiToRaw::DigiToRaw]"
0032                             << " Constructing object...";
0033     }
0034     bufferGenerator_.setReadoutMode(mode_);
0035   }
0036 
0037   // -----------------------------------------------------------------------------
0038   /** */
0039   DigiToRaw::~DigiToRaw() {
0040     if (edm::isDebugEnabled()) {
0041       LogDebug("DigiToRaw") << "[sistrip::DigiToRaw::~DigiToRaw]"
0042                             << " Destructing object...";
0043     }
0044   }
0045 
0046   // -----------------------------------------------------------------------------
0047   /** 
0048       Input: DetSetVector of SiStripDigis. Output: FEDRawDataCollection.
0049       Retrieves and iterates through FED buffers, extract FEDRawData
0050       from collection and (optionally) dumps raw data to stdout, locates
0051       start of FED buffer by identifying DAQ header, creates new
0052       Fed9UEvent object using current FEDRawData buffer, dumps FED
0053       buffer to stdout, retrieves data from various header fields
0054   */
0055   void DigiToRaw::createFedBuffers(edm::Event& event,
0056                                    edm::ESHandle<SiStripFedCabling>& cabling,
0057                                    edm::Handle<edm::DetSetVector<SiStripDigi> >& collection,
0058                                    std::unique_ptr<FEDRawDataCollection>& buffers) {
0059     createFedBuffers_(event, cabling, collection, buffers, true);
0060   }
0061 
0062   void DigiToRaw::createFedBuffers(edm::Event& event,
0063                                    edm::ESHandle<SiStripFedCabling>& cabling,
0064                                    edm::Handle<edm::DetSetVector<SiStripRawDigi> >& collection,
0065                                    std::unique_ptr<FEDRawDataCollection>& buffers) {
0066     createFedBuffers_(event, cabling, collection, buffers, false);
0067   }
0068 
0069   //with copy of headers from initial raw data collection (raw->digi->raw)
0070   void DigiToRaw::createFedBuffers(edm::Event& event,
0071                                    edm::ESHandle<SiStripFedCabling>& cabling,
0072                                    edm::Handle<FEDRawDataCollection>& rawbuffers,
0073                                    edm::Handle<edm::DetSetVector<SiStripDigi> >& collection,
0074                                    std::unique_ptr<FEDRawDataCollection>& buffers) {
0075     createFedBuffers_(event, cabling, rawbuffers, collection, buffers, true);
0076   }
0077 
0078   void DigiToRaw::createFedBuffers(edm::Event& event,
0079                                    edm::ESHandle<SiStripFedCabling>& cabling,
0080                                    edm::Handle<FEDRawDataCollection>& rawbuffers,
0081                                    edm::Handle<edm::DetSetVector<SiStripRawDigi> >& collection,
0082                                    std::unique_ptr<FEDRawDataCollection>& buffers) {
0083     createFedBuffers_(event, cabling, rawbuffers, collection, buffers, false);
0084   }
0085 
0086   template <class Digi_t>
0087   void DigiToRaw::createFedBuffers_(edm::Event& event,
0088                                     edm::ESHandle<SiStripFedCabling>& cabling,
0089                                     edm::Handle<edm::DetSetVector<Digi_t> >& collection,
0090                                     std::unique_ptr<FEDRawDataCollection>& buffers,
0091                                     bool zeroSuppressed) {
0092     edm::Handle<FEDRawDataCollection> rawbuffers;
0093     //CAMM initialise to some dummy empty buffers??? Or OK like this ?
0094     createFedBuffers_(event, cabling, rawbuffers, collection, buffers, zeroSuppressed);
0095   }
0096 
0097   template <class Digi_t>
0098   void DigiToRaw::createFedBuffers_(edm::Event& event,
0099                                     edm::ESHandle<SiStripFedCabling>& cabling,
0100                                     edm::Handle<FEDRawDataCollection>& rawbuffers,
0101                                     edm::Handle<edm::DetSetVector<Digi_t> >& collection,
0102                                     std::unique_ptr<FEDRawDataCollection>& buffers,
0103                                     bool zeroSuppressed) {
0104     const bool dataIsAlready8BitTruncated =
0105         zeroSuppressed &&
0106         (!(
0107             //for special mode premix raw, data is zero-suppressed but not converted to 8 bit
0108             (mode_ == READOUT_MODE_PREMIX_RAW)
0109             // the same goes for 10bit ZS modes
0110             || ((mode_ == READOUT_MODE_ZERO_SUPPRESSED) && (packetCode_ == PACKET_CODE_ZERO_SUPPRESSED10)) ||
0111             (mode_ == READOUT_MODE_ZERO_SUPPRESSED_LITE10) ||
0112             (mode_ == READOUT_MODE_ZERO_SUPPRESSED_LITE10_CMOVERRIDE)));
0113     try {
0114       //set the L1ID to use in the buffers
0115       bufferGenerator_.setL1ID(0xFFFFFF & event.id().event());
0116       auto fed_ids = cabling->fedIds();
0117 
0118       //copy header if valid rawbuffers handle
0119       if (rawbuffers.isValid()) {
0120         if (edm::isDebugEnabled()) {
0121           edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0122                                        << " Valid raw buffers, getting headers from them..."
0123                                        << " Number of feds: " << fed_ids.size() << " between " << *(fed_ids.begin())
0124                                        << " and " << *(fed_ids.end());
0125         }
0126 
0127         const FEDRawDataCollection& rawDataCollection = *rawbuffers;
0128 
0129         for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ++ifed) {
0130           const FEDRawData& rawfedData = rawDataCollection.FEDData(*ifed);
0131 
0132           if (edm::isDebugEnabled()) {
0133             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0134                                          << "Fed " << *ifed << " : size of buffer = " << rawfedData.size();
0135           }
0136 
0137           //need to construct full object to copy full header
0138           if (rawfedData.size() == 0)
0139             warnings_.add("Invalid raw data for FED, skipping", fmt::format("id {0}", *ifed));
0140           const auto st_buffer = preconstructCheckFEDBuffer(rawfedData, true);
0141           if (FEDBufferStatusCode::SUCCESS != st_buffer) {
0142             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0143                                          << " Could not construct FEDBuffer for FED " << *ifed << std::endl;
0144             continue;
0145           }
0146           sistrip::FEDBuffer fedbuffer{rawfedData, true};
0147           const auto st_chan = fedbuffer.findChannels();
0148           if (FEDBufferStatusCode::SUCCESS != st_chan) {
0149             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0150                                          << " Could not construct FEDBuffer for FED " << *ifed << std::endl;
0151           }
0152           if (fedbuffer.headerType() == sistrip::HEADER_TYPE_INVALID) {
0153             warnings_.add("Invalid header type for FED, skipping", fmt::format("id {0}", *ifed));
0154             continue;
0155           }
0156 
0157           if (edm::isDebugEnabled()) {
0158             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0159                                          << " Original header type: " << fedbuffer.headerType();
0160           }
0161 
0162           bufferGenerator_.setHeaderType(FEDHeaderType::HEADER_TYPE_FULL_DEBUG);
0163           //fedbuffer.headerType());
0164           bufferGenerator_.daqHeader() = fedbuffer.daqHeader();
0165           bufferGenerator_.daqTrailer() = fedbuffer.daqTrailer();
0166 
0167           bufferGenerator_.trackerSpecialHeader() = fedbuffer.trackerSpecialHeader();
0168           bufferGenerator_.setReadoutMode(mode_);
0169 
0170           if (edm::isDebugEnabled()) {
0171             std::ostringstream debugStream;
0172             if (ifed == fed_ids.begin()) {
0173               bufferGenerator_.trackerSpecialHeader().print(std::cout);
0174               std::cout << std::endl;
0175             }
0176             bufferGenerator_.trackerSpecialHeader().print(debugStream);
0177             edm::LogWarning("DigiToRaw")
0178                 << "[sistrip::DigiToRaw::createFedBuffers_]"
0179                 << " Tracker special header apveAddress: "
0180                 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().apveAddress())
0181                 << " - event type = " << bufferGenerator_.getDAQEventType()
0182                 << " - buffer format = " << bufferGenerator_.getBufferFormat() << "\n"
0183                 << " - SpecialHeader bufferformat " << bufferGenerator_.trackerSpecialHeader().bufferFormat()
0184                 << " - headertype " << bufferGenerator_.trackerSpecialHeader().headerType() << " - readoutmode "
0185                 << bufferGenerator_.trackerSpecialHeader().readoutMode() << " - apvaddrregister " << std::hex
0186                 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().apvAddressErrorRegister())
0187                 << " - feenabledregister " << std::hex
0188                 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().feEnableRegister())
0189                 << " - feoverflowregister " << std::hex
0190                 << static_cast<int>(bufferGenerator_.trackerSpecialHeader().feOverflowRegister())
0191                 << " - statusregister " << bufferGenerator_.trackerSpecialHeader().fedStatusRegister() << "\n"
0192                 << " SpecialHeader: " << debugStream.str();
0193           }
0194 
0195           std::unique_ptr<FEDFEHeader> tempFEHeader(fedbuffer.feHeader()->clone());
0196           FEDFullDebugHeader* fedFeHeader = dynamic_cast<FEDFullDebugHeader*>(tempFEHeader.get());
0197           if (edm::isDebugEnabled()) {
0198             std::ostringstream debugStream;
0199             if (ifed == fed_ids.begin()) {
0200               std::cout << "FEHeader before transfer: " << std::endl;
0201               fedFeHeader->print(std::cout);
0202               std::cout << std::endl;
0203             }
0204             fedFeHeader->print(debugStream);
0205             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0206                                          << " length of original feHeader: " << fedFeHeader->lengthInBytes() << "\n"
0207                                          << debugStream.str();
0208           }
0209           //status registers
0210           (bufferGenerator_.feHeader()).setBEStatusRegister(fedFeHeader->beStatusRegister());
0211           (bufferGenerator_.feHeader()).setDAQRegister2(fedFeHeader->daqRegister2());
0212           (bufferGenerator_.feHeader()).setDAQRegister(fedFeHeader->daqRegister());
0213           for (uint8_t iFE = 1; iFE < 6; iFE++) {
0214             (bufferGenerator_.feHeader())
0215                 .set32BitReservedRegister(iFE, fedFeHeader->get32BitWordFrom(fedFeHeader->feWord(iFE) + 10));
0216           }
0217 
0218           std::vector<bool> feEnabledVec;
0219           feEnabledVec.resize(FEUNITS_PER_FED, true);
0220           for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0221             feEnabledVec[iFE] = fedbuffer.trackerSpecialHeader().feEnabled(iFE);
0222             (bufferGenerator_.feHeader()).setFEUnitMajorityAddress(iFE, fedFeHeader->feUnitMajorityAddress(iFE));
0223             for (uint8_t iFEUnitChannel = 0; iFEUnitChannel < FEDCH_PER_FEUNIT; iFEUnitChannel++) {
0224               (bufferGenerator_.feHeader())
0225                   .setChannelStatus(iFE, iFEUnitChannel, fedFeHeader->getChannelStatus(iFE, iFEUnitChannel));
0226             }  //loop on channels
0227           }    //loop on fe units
0228           bufferGenerator_.setFEUnitEnables(feEnabledVec);
0229 
0230           if (edm::isDebugEnabled()) {
0231             std::ostringstream debugStream;
0232             if (ifed == fed_ids.begin()) {
0233               std::cout << "\nFEHeader after transfer: " << std::endl;
0234               bufferGenerator_.feHeader().print(std::cout);
0235               std::cout << std::endl;
0236             }
0237             bufferGenerator_.feHeader().print(debugStream);
0238             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0239                                          << " length of feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
0240                                          << "\n"
0241                                          << debugStream.str();
0242           }
0243           auto conns = cabling->fedConnections(*ifed);
0244 
0245           FEDStripData fedData(dataIsAlready8BitTruncated);
0246 
0247           for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
0248             // Determine FED key from cabling
0249             uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
0250 
0251             // Determine whether DetId or FED key should be used to index digi containers
0252             uint32_t key = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? fed_key : iconn->detId();
0253 
0254             // Check key is non-zero and valid
0255             if (!key || (key == sistrip::invalid32_)) {
0256               continue;
0257             }
0258 
0259             // Determine APV pair number (needed only when using DetId)
0260             uint16_t ipair = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? 0 : iconn->apvPairNumber();
0261 
0262             FEDStripData::ChannelData& chanData = fedData[iconn->fedCh()];
0263 
0264             // Find digis for DetID in collection
0265             if (!collection.isValid()) {
0266               if (edm::isDebugEnabled()) {
0267                 edm::LogWarning("DigiToRaw") << "[DigiToRaw::createFedBuffers] "
0268                                              << "digis collection is not valid...";
0269               }
0270               break;
0271             }
0272             typename std::vector<edm::DetSet<Digi_t> >::const_iterator digis = collection->find(key);
0273             if (digis == collection->end()) {
0274               continue;
0275             }
0276 
0277             typename edm::DetSet<Digi_t>::const_iterator idigi, digis_begin(digis->data.begin());
0278             for (idigi = digis_begin; idigi != digis->data.end(); idigi++) {
0279               if (STRIP(idigi, digis_begin) < ipair * 256 || STRIP(idigi, digis_begin) > ipair * 256 + 255) {
0280                 continue;
0281               }
0282               const unsigned short strip = STRIP(idigi, digis_begin) % 256;
0283 
0284               if (strip >= STRIPS_PER_FEDCH) {
0285                 if (edm::isDebugEnabled()) {
0286                   std::stringstream ss;
0287                   ss << "[sistrip::DigiToRaw::createFedBuffers]"
0288                      << " strip >= strips_per_fedCh";
0289                   edm::LogWarning("DigiToRaw") << ss.str();
0290                 }
0291                 continue;
0292               }
0293 
0294               // check if value already exists
0295               if (edm::isDebugEnabled()) {
0296                 const uint16_t value = 0;  //chanData[strip];
0297                 if (value && value != (*idigi).adc()) {
0298                   std::stringstream ss;
0299                   ss << "[sistrip::DigiToRaw::createFedBuffers]"
0300                      << " Incompatible ADC values in buffer!"
0301                      << "  FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
0302                      << "  DetStrip: " << STRIP(idigi, digis_begin) << "  FedChStrip: " << strip
0303                      << "  AdcValue: " << (*idigi).adc() << "  RawData[" << strip << "]: " << value;
0304                   edm::LogWarning("DigiToRaw") << ss.str();
0305                 }
0306               }
0307 
0308               // Add digi to buffer
0309               chanData[strip] = (*idigi).adc();
0310             }
0311           }
0312           // if ((*idigi).strip() >= (ipair+1)*256) break;
0313 
0314           if (edm::isDebugEnabled()) {
0315             edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
0316                                          << "Almost at the end...";
0317           }
0318           //create the buffer
0319           FEDRawData& fedrawdata = buffers->FEDData(*ifed);
0320           bufferGenerator_.generateBuffer(&fedrawdata, fedData, *ifed, packetCode_);
0321 
0322           if (edm::isDebugEnabled()) {
0323             std::ostringstream debugStream;
0324             bufferGenerator_.feHeader().print(debugStream);
0325             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0326                                          << " length of final feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
0327                                          << "\n"
0328                                          << debugStream.str();
0329           }
0330         }  //loop on fedids
0331         if (edm::isDebugEnabled()) {
0332           edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0333                                        << "end of first loop on feds";
0334         }
0335 
0336       }  //end of workflow for copying header, below is workflow without copying header
0337       else {
0338         if (edm::isDebugEnabled()) {
0339           edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0340                                        << "Now getting the digis..."
0341                                        << " Number of feds: " << fed_ids.size() << " between " << *(fed_ids.begin())
0342                                        << " and " << *(fed_ids.end());
0343         }
0344 
0345         for (auto ifed = fed_ids.begin(); ifed != fed_ids.end(); ++ifed) {
0346           auto conns = cabling->fedConnections(*ifed);
0347 
0348           FEDStripData fedData(dataIsAlready8BitTruncated);
0349 
0350           for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
0351             // Determine FED key from cabling
0352             uint32_t fed_key = ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
0353 
0354             // Determine whether DetId or FED key should be used to index digi containers
0355             uint32_t key = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? fed_key : iconn->detId();
0356 
0357             // Check key is non-zero and valid
0358             if (!key || (key == sistrip::invalid32_)) {
0359               continue;
0360             }
0361 
0362             // Determine APV pair number (needed only when using DetId)
0363             uint16_t ipair = (useFedKey_ || mode_ == READOUT_MODE_SCOPE) ? 0 : iconn->apvPairNumber();
0364 
0365             FEDStripData::ChannelData& chanData = fedData[iconn->fedCh()];
0366 
0367             // Find digis for DetID in collection
0368             if (!collection.isValid()) {
0369               if (edm::isDebugEnabled()) {
0370                 edm::LogWarning("DigiToRaw") << "[DigiToRaw::createFedBuffers] "
0371                                              << "digis collection is not valid...";
0372               }
0373               break;
0374             }
0375             typename std::vector<edm::DetSet<Digi_t> >::const_iterator digis = collection->find(key);
0376             if (digis == collection->end()) {
0377               continue;
0378             }
0379 
0380             typename edm::DetSet<Digi_t>::const_iterator idigi, digis_begin(digis->data.begin());
0381             for (idigi = digis_begin; idigi != digis->data.end(); idigi++) {
0382               if (STRIP(idigi, digis_begin) < ipair * 256 || STRIP(idigi, digis_begin) > ipair * 256 + 255) {
0383                 continue;
0384               }
0385               const unsigned short strip = STRIP(idigi, digis_begin) % 256;
0386 
0387               if (strip >= STRIPS_PER_FEDCH) {
0388                 if (edm::isDebugEnabled()) {
0389                   std::stringstream ss;
0390                   ss << "[sistrip::DigiToRaw::createFedBuffers]"
0391                      << " strip >= strips_per_fedCh";
0392                   edm::LogWarning("DigiToRaw") << ss.str();
0393                 }
0394                 continue;
0395               }
0396 
0397               // check if value already exists
0398               if (edm::isDebugEnabled()) {
0399                 const uint16_t value = 0;  //chanData[strip];
0400                 if (value && value != (*idigi).adc()) {
0401                   std::stringstream ss;
0402                   ss << "[sistrip::DigiToRaw::createFedBuffers]"
0403                      << " Incompatible ADC values in buffer!"
0404                      << "  FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
0405                      << "  DetStrip: " << STRIP(idigi, digis_begin) << "  FedChStrip: " << strip
0406                      << "  AdcValue: " << (*idigi).adc() << "  RawData[" << strip << "]: " << value;
0407                   edm::LogWarning("DigiToRaw") << ss.str();
0408                 }
0409               }
0410 
0411               // Add digi to buffer
0412               chanData[strip] = (*idigi).adc();
0413             }
0414           }
0415           // if ((*idigi).strip() >= (ipair+1)*256) break;
0416 
0417           if (edm::isDebugEnabled()) {
0418             edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
0419                                          << "Almost at the end...";
0420           }
0421           //create the buffer
0422           FEDRawData& fedrawdata = buffers->FEDData(*ifed);
0423           bufferGenerator_.generateBuffer(&fedrawdata, fedData, *ifed, packetCode_);
0424 
0425           if (edm::isDebugEnabled()) {
0426             std::ostringstream debugStream;
0427             bufferGenerator_.feHeader().print(debugStream);
0428             edm::LogWarning("DigiToRaw") << "[sistrip::DigiToRaw::createFedBuffers_]"
0429                                          << " length of final feHeader: " << bufferGenerator_.feHeader().lengthInBytes()
0430                                          << "\n"
0431                                          << debugStream.str();
0432           }
0433         }  //loop on feds
0434       }    //end if-else for copying header
0435     }      //try
0436     catch (const std::exception& e) {
0437       if (edm::isDebugEnabled()) {
0438         edm::LogWarning("DigiToRaw") << "DigiToRaw::createFedBuffers] "
0439                                      << "Exception caught : " << e.what();
0440       }
0441     }
0442   }
0443 
0444   inline uint16_t DigiToRaw::STRIP(const edm::DetSet<SiStripDigi>::const_iterator& it,
0445                                    const edm::DetSet<SiStripDigi>::const_iterator& begin) const {
0446     return it->strip();
0447   }
0448   inline uint16_t DigiToRaw::STRIP(const edm::DetSet<SiStripRawDigi>::const_iterator& it,
0449                                    const edm::DetSet<SiStripRawDigi>::const_iterator& begin) const {
0450     return it - begin;
0451   }
0452 
0453 }  // namespace sistrip