Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-31 23:14:02

0001 /* \file SiStripSpyUnpacker.cc
0002  * \brief Source code for the SpyChannel unpacking factory.
0003  */
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 
0007 #include "DataFormats/Common/interface/DetSetVector.h"
0008 #include "DataFormats/Common/interface/DetSet.h"
0009 
0010 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0011 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0012 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0013 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0014 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0015 
0016 #include "EventFilter/SiStripRawToDigi/interface/SiStripDetSetVectorFiller.h"
0017 
0018 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
0019 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUnpacker.h"
0020 
0021 #include <algorithm>
0022 #include <vector>
0023 #include <ext/algorithm>
0024 
0025 using namespace std;
0026 
0027 namespace sistrip {
0028 
0029   SpyUnpacker::SpyUnpacker(const bool allowIncompleteEvents) : allowIncompleteEvents_(allowIncompleteEvents) {
0030     if (edm::isDebugEnabled()) {
0031       LogTrace("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
0032                                      << " Constructing object...";
0033     }
0034   }  // end of SpyUnpacker constructor.
0035 
0036   SpyUnpacker::~SpyUnpacker() {
0037     if (edm::isDebugEnabled()) {
0038       LogTrace("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
0039                                      << " Destructing object...";
0040     }
0041   }  // end of SpyUnpacker destructor.
0042 
0043   void SpyUnpacker::createDigis(const SiStripFedCabling& cabling,
0044                                 const FEDRawDataCollection& buffers,
0045                                 RawDigis* pDigis,
0046                                 const std::vector<uint32_t>& ids,
0047                                 Counters* pTotalEventCounts,
0048                                 Counters* pL1ACounts,
0049                                 uint32_t* aRunRef) const {
0050     //create DSV filler to fill output
0051 
0052     //As of Feb 2010, bug in DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h:
0053     //number of feds=max-min+1 (440...). Corrected in head of DataFormats/SiStripCommon package.
0054 
0055     uint16_t nFeds = static_cast<uint16_t>(FED_ID_MAX - FED_ID_MIN + 1);
0056 
0057     RawDigiDetSetVectorFiller dsvFiller(nFeds * FEDCH_PER_FED, nFeds * FEDCH_PER_FED * SPY_SAMPLES_PER_CHANNEL);
0058 
0059     //check if FEDs found in cabling map and event data
0060     if (edm::isDebugEnabled()) {
0061       if (cabling.fedIds().empty()) {
0062         edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
0063                                               << " No FEDs found in cabling map!";
0064       }
0065     }
0066 
0067     //retrieve FED ids from cabling map and iterate through
0068     std::vector<uint32_t>::const_iterator ifed = ids.begin();
0069     std::vector<uint32_t>::const_iterator endfed = ids.end();
0070 
0071     //reference value for run number
0072     //encoded per fed but should be the same for all feds
0073     uint32_t lRef = 0;
0074 
0075     //initialise counter vectors to FED_ID_MAX+1
0076     pTotalEventCounts->resize(FED_ID_MAX + 1, 0);
0077     pL1ACounts->resize(FED_ID_MAX + 1, 0);
0078 
0079     for (; ifed != endfed; ++ifed) {
0080       uint32_t lFedId = (*ifed);
0081 
0082       //check the fedid is valid:
0083       if (lFedId < FED_ID_MIN || lFedId > FED_ID_MAX) {
0084         if (edm::isDebugEnabled()) {
0085           edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
0086                                                 << " Invalid FED id provided: " << lFedId;
0087         }
0088         continue;
0089       }
0090 
0091       //retrieve FED raw data for given FED
0092       const FEDRawData& input = buffers.FEDData(static_cast<int>(lFedId));
0093       //check on FEDRawData pointer
0094       if (!input.data()) {
0095         if (edm::isDebugEnabled()) {
0096           edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
0097                                                 << " NULL pointer to FEDRawData for FED id " << lFedId;
0098         }
0099         continue;
0100       }
0101       //check on FEDRawData size
0102       if (!input.size()) {
0103         if (edm::isDebugEnabled()) {
0104           edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
0105                                                 << " FEDRawData has zero size for FED id " << lFedId;
0106         }
0107         continue;
0108       }
0109 
0110       //get the cabling connections for this FED
0111       auto conns = cabling.fedConnections(lFedId);
0112 
0113       //construct FEDBuffer
0114       const auto st_buffer = preconstructCheckFEDSpyBuffer(input);
0115       if (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
0116         edm::LogWarning("SiStripSpyUnpacker")
0117             << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": "
0118             << "An exception of category 'FEDBuffer' occurred.\n"
0119             << st_buffer;
0120         continue;
0121       }
0122       const sistrip::FEDSpyBuffer buffer{input};
0123       if (!buffer.doChecks() && !allowIncompleteEvents_) {
0124         edm::LogWarning("SiStripSpyUnpacker")
0125             << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": "
0126             << "An exception of category 'FEDSpyBuffer' occurred.\n"
0127             << "FED Buffer check fails for FED ID " << lFedId << ".";
0128         continue;
0129       }
0130       // end of buffer reset try.
0131 
0132       // Get the event counter values
0133       uint32_t totalEvCount = buffer.spyHeaderTotalEventCount();
0134       uint32_t l1ID = buffer.spyHeaderL1ID();
0135 
0136       uint32_t lGRun = buffer.globalRunNumber();
0137 
0138       //for the first fed, put it as reference value for others
0139       if (lRef == 0)
0140         lRef = lGRun;
0141       if (lGRun != lRef) {
0142         edm::LogError("SiStripSpyUnpacker") << " -- Global run encoded in buffer for FED " << lFedId << ": " << lGRun
0143                                             << " is different from reference value " << lRef << std::endl;
0144       }
0145 
0146       // Add event counters
0147       (*pL1ACounts)[lFedId] = l1ID;
0148       (*pTotalEventCounts)[lFedId] = totalEvCount;
0149 
0150       //iterate through FED channels, extract payload and create Digis
0151       std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
0152       std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
0153       for (; iconn != endconn; ++iconn) {
0154         //check if fed connection is valid
0155         if (!iconn->isConnected()) {
0156           continue;
0157         }
0158 
0159         //FED channel
0160         uint16_t chan = iconn->fedCh();
0161 
0162         //check values are valid:
0163         if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId) {
0164           if (edm::isDebugEnabled()) {
0165             std::ostringstream ss;
0166             ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId
0167                << ", iconn->fedCh() = " << chan << std::endl;
0168             edm::LogWarning("SiStripSpyUnpacker") << ss.str();
0169           }
0170           continue;
0171         }
0172 
0173         //check FED channel
0174         if (!buffer.channelGood(chan)) {
0175           if (edm::isDebugEnabled()) {
0176             std::ostringstream ss;
0177             ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
0178             edm::LogWarning("SiStripSpyUnpacker") << ss.str();
0179           }
0180           continue;
0181         }
0182 
0183         //determine key from cabling
0184         const uint32_t key = ((lFedId & sistrip::invalid_) << 16) | (chan & sistrip::invalid_);
0185 
0186         // Start a new channel in the filler
0187         dsvFiller.newChannel(key);
0188         // Create the unpacker object
0189         sistrip::FEDSpyChannelUnpacker unpacker = sistrip::FEDSpyChannelUnpacker(buffer.channel(chan));
0190 
0191         // Unpack the data into dsv filler
0192         while (unpacker.hasData()) {
0193           dsvFiller.addItem(SiStripRawDigi{unpacker.adc()});
0194           unpacker++;
0195         }
0196       }  // end of channel loop
0197 
0198     }  //fed loop
0199 
0200     //set the run number
0201     *aRunRef = lRef;
0202 
0203     //create DSV to return
0204     std::unique_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
0205     pDigis->swap(*pResult);
0206 
0207   }  // end of SpyUnpacker::createDigis method.
0208 
0209 }  // namespace sistrip