Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 // Module to import spy channel data into matching events
0002 
0003 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyEventMatcher.h"
0004 #ifdef SiStripMonitorHardware_BuildEventMatchingCode
0005 
0006 #include "FWCore/Utilities/interface/EDGetToken.h"
0007 #include "FWCore/Framework/interface/stream/EDFilter.h"
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/Framework/interface/EventSetup.h"
0010 #include "FWCore/Framework/interface/ESWatcher.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0014 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
0015 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0016 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0017 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
0018 #include "DataFormats/Common/interface/DetSetVector.h"
0019 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0020 #include "DataFormats/Common/interface/Handle.h"
0021 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUtilities.h"
0022 #include "FWCore/Utilities/interface/Exception.h"
0023 #include <memory>
0024 #include <vector>
0025 
0026 using edm::LogError;
0027 using edm::LogInfo;
0028 
0029 namespace sistrip {
0030 
0031   class SpyEventMatcherModule : public edm::stream::EDFilter<> {
0032   public:
0033     SpyEventMatcherModule(const edm::ParameterSet& config);
0034     ~SpyEventMatcherModule() override;
0035     void beginStream(edm::StreamID) override;
0036     bool filter(edm::Event& event, const edm::EventSetup& eventSetup) override;
0037 
0038   private:
0039     void findL1IDandAPVAddress(const edm::Event& event,
0040                                const SiStripFedCabling& cabling,
0041                                uint32_t& l1ID,
0042                                uint8_t& apvAddress) const;
0043     void copyData(const uint32_t eventId,
0044                   const uint8_t apvAddress,
0045                   const SpyEventMatcher::SpyEventList* matches,
0046                   edm::Event& event,
0047                   const SiStripFedCabling& cabling) const;
0048 
0049     static const char* const messageLabel_;
0050     const bool filterNonMatchingEvents_;
0051     const bool doMerge_;
0052     const edm::InputTag primaryStreamRawDataTag_;
0053     edm::EDGetTokenT<FEDRawDataCollection> primaryStreamRawDataToken_;
0054     std::unique_ptr<SpyEventMatcher> spyEventMatcher_;
0055     edm::ESGetToken<SiStripFedCabling, SiStripFedCablingRcd> fedCablingToken_;
0056     const SiStripFedCabling* fedCabling_;
0057     edm::ESWatcher<SiStripFedCablingRcd> cablingWatcher_;
0058     void updateFedCabling(const SiStripFedCablingRcd& rcd);
0059   };
0060 
0061 }  // namespace sistrip
0062 
0063 namespace sistrip {
0064 
0065   const char* const SpyEventMatcherModule::messageLabel_ = "SiStripSpyDataMergeModule";
0066 
0067   SpyEventMatcherModule::SpyEventMatcherModule(const edm::ParameterSet& config)
0068       : filterNonMatchingEvents_(config.getParameter<bool>("FilterNonMatchingEvents")),
0069         doMerge_(config.getParameter<bool>("MergeData")),
0070         primaryStreamRawDataTag_(config.getParameter<edm::InputTag>("PrimaryEventRawDataTag")),
0071         spyEventMatcher_(new SpyEventMatcher(config)),
0072         fedCablingToken_(esConsumes<>()),
0073         cablingWatcher_(this, &SpyEventMatcherModule::updateFedCabling) {
0074     primaryStreamRawDataToken_ = consumes<FEDRawDataCollection>(primaryStreamRawDataTag_);
0075     if (doMerge_) {
0076       produces<FEDRawDataCollection>("RawSpyData");
0077       produces<std::vector<uint32_t> >("SpyTotalEventCount");
0078       produces<std::vector<uint32_t> >("SpyL1ACount");
0079       produces<std::vector<uint32_t> >("SpyAPVAddress");
0080       produces<edm::DetSetVector<SiStripRawDigi> >("SpyScope");
0081       produces<edm::DetSetVector<SiStripRawDigi> >("SpyPayload");
0082       produces<edm::DetSetVector<SiStripRawDigi> >("SpyReordered");
0083       produces<edm::DetSetVector<SiStripRawDigi> >("SpyVirginRaw");
0084     }
0085   }
0086 
0087   SpyEventMatcherModule::~SpyEventMatcherModule() {}
0088 
0089   void SpyEventMatcherModule::updateFedCabling(const SiStripFedCablingRcd& rcd) {
0090     fedCabling_ = &rcd.get(fedCablingToken_);
0091   }
0092 
0093   void SpyEventMatcherModule::beginStream(edm::StreamID) { spyEventMatcher_->initialize(); }
0094 
0095   bool SpyEventMatcherModule::filter(edm::Event& event, const edm::EventSetup& eventSetup) {
0096     cablingWatcher_.check(eventSetup);
0097     uint8_t apvAddress = 0;
0098     uint32_t eventId = 0;
0099     try {
0100       findL1IDandAPVAddress(event, *fedCabling_, eventId, apvAddress);
0101     } catch (const cms::Exception& e) {
0102       LogError(messageLabel_) << e.what();
0103       return (filterNonMatchingEvents_ ? false : true);
0104     }
0105     const SpyEventMatcher::SpyEventList* matches = spyEventMatcher_->matchesForEvent(eventId, apvAddress);
0106     if (matches) {
0107       if (doMerge_) {
0108         copyData(eventId, apvAddress, matches, event, *fedCabling_);
0109       }
0110       return true;
0111     } else {
0112       return (filterNonMatchingEvents_ ? false : true);
0113     }
0114   }
0115 
0116   void SpyEventMatcherModule::findL1IDandAPVAddress(const edm::Event& event,
0117                                                     const SiStripFedCabling& cabling,
0118                                                     uint32_t& l1ID,
0119                                                     uint8_t& apvAddress) const {
0120     edm::Handle<FEDRawDataCollection> fedRawDataHandle;
0121     event.getByToken(primaryStreamRawDataToken_, fedRawDataHandle);
0122     const FEDRawDataCollection& fedRawData = *fedRawDataHandle;
0123     for (auto iFedId = cabling.fedIds().begin(); iFedId != cabling.fedIds().end(); ++iFedId) {
0124       const FEDRawData& data = fedRawData.FEDData(*iFedId);
0125       const auto st_buffer = preconstructCheckFEDBuffer(data);
0126       if (FEDBufferStatusCode::SUCCESS != st_buffer) {
0127         LogInfo(messageLabel_) << "Failed to build FED buffer for FED ID " << *iFedId
0128                                << ". Exception was: An exception of category 'FEDBuffer' occurred.\n"
0129                                << st_buffer << " (see debug output for details)";
0130         continue;
0131       }
0132       FEDBuffer buffer{data};
0133       const auto st_chan = buffer.findChannels();
0134       if (FEDBufferStatusCode::SUCCESS != st_chan) {
0135         LogDebug(messageLabel_) << "Failed to build FED buffer for FED ID " << *iFedId << ". Exception was " << st_chan
0136                                 << " (see above for more details)";
0137         continue;
0138       }
0139       if (!buffer.doChecks(true)) {
0140         LogDebug(messageLabel_) << "Buffer check failed for FED ID " << *iFedId;
0141         continue;
0142       }
0143       l1ID = buffer.daqLvl1ID();
0144       apvAddress = buffer.trackerSpecialHeader().apveAddress();
0145       if (apvAddress != 0) {
0146         return;
0147       } else {
0148         if (buffer.trackerSpecialHeader().headerType() != HEADER_TYPE_FULL_DEBUG) {
0149           continue;
0150         }
0151         const FEDFullDebugHeader* header = dynamic_cast<const FEDFullDebugHeader*>(buffer.feHeader());
0152         auto connections = cabling.fedConnections(*iFedId);
0153         for (auto iConn = connections.begin(); iConn != connections.end(); ++iConn) {
0154           if (!iConn->isConnected()) {
0155             continue;
0156           }
0157           if (!buffer.channelGood(iConn->fedCh(), true)) {
0158             continue;
0159           } else {
0160             apvAddress = header->feUnitMajorityAddress(iConn->fedCh() / FEDCH_PER_FEUNIT);
0161             return;
0162           }
0163         }
0164       }
0165     }
0166     //if we haven't already found an acceptable alternative, throw an exception
0167     throw cms::Exception(messageLabel_) << "Failed to get L1ID/APV address from any FED";
0168   }
0169 
0170   void SpyEventMatcherModule::copyData(const uint32_t eventId,
0171                                        const uint8_t apvAddress,
0172                                        const SpyEventMatcher::SpyEventList* matches,
0173                                        edm::Event& event,
0174                                        const SiStripFedCabling& cabling) const {
0175     SpyEventMatcher::SpyDataCollections matchedCollections;
0176     spyEventMatcher_->getMatchedCollections(eventId, apvAddress, matches, cabling, matchedCollections);
0177     if (matchedCollections.rawData.get())
0178       event.put(std::move(matchedCollections.rawData), "RawSpyData");
0179     if (matchedCollections.totalEventCounters.get())
0180       event.put(std::move(matchedCollections.totalEventCounters), "SpyTotalEventCount");
0181     if (matchedCollections.l1aCounters.get())
0182       event.put(std::move(matchedCollections.l1aCounters), "SpyL1ACount");
0183     if (matchedCollections.apvAddresses.get())
0184       event.put(std::move(matchedCollections.apvAddresses), "SpyAPVAddress");
0185     if (matchedCollections.scopeDigis.get())
0186       event.put(std::move(matchedCollections.scopeDigis), "SpyScope");
0187     if (matchedCollections.payloadDigis.get())
0188       event.put(std::move(matchedCollections.payloadDigis), "SpyPayload");
0189     if (matchedCollections.reorderedDigis.get())
0190       event.put(std::move(matchedCollections.reorderedDigis), "SpyReordered");
0191     if (matchedCollections.virginRawDigis.get())
0192       event.put(std::move(matchedCollections.virginRawDigis), "SpyVirginRaw");
0193   }
0194 
0195 }  // namespace sistrip
0196 
0197 #include "FWCore/Framework/interface/MakerMacros.h"
0198 #include <cstdint>
0199 typedef sistrip::SpyEventMatcherModule SiStripSpyEventMatcherModule;
0200 DEFINE_FWK_MODULE(SiStripSpyEventMatcherModule);
0201 
0202 #endif  //SiStripMonitorHardware_BuildEventMatchingCode