Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:18:28

0001 /** \class HLTLevel1Pattern
0002  *
0003  *
0004  *  This class is an EDFilter
0005  *  that checks for a specific pattern of L1 accept/reject in 5 BX's for a given L1 bit
0006  *  It can be configured to use or ignore the L1 trigger mask
0007  *
0008  *
0009  *  \author Andrea Bocci
0010  *
0011  */
0012 
0013 #include <vector>
0014 
0015 #include "FWCore/Framework/interface/ESWatcher.h"
0016 #include "FWCore/Framework/interface/Frameworkfwd.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/stream/EDFilter.h"
0019 #include "FWCore/Utilities/interface/InputTag.h"
0020 #include "FWCore/Utilities/interface/Exception.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0022 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0023 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0024 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
0025 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskTechTrigRcd.h"
0026 #include "CondFormats/DataRecord/interface/L1GtTriggerMaskAlgoTrigRcd.h"
0027 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
0028 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenuFwd.h"
0029 #include "CondFormats/L1TObjects/interface/L1GtTriggerMask.h"
0030 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0031 
0032 //
0033 // class declaration
0034 //
0035 
0036 class HLTLevel1Pattern : public edm::stream::EDFilter<> {
0037 public:
0038   explicit HLTLevel1Pattern(const edm::ParameterSet&);
0039   ~HLTLevel1Pattern() override;
0040   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0041   bool filter(edm::Event&, const edm::EventSetup&) override;
0042 
0043 private:
0044   const edm::InputTag m_gtReadoutRecord;
0045   const edm::EDGetTokenT<L1GlobalTriggerReadoutRecord> m_gtReadoutRecordToken;
0046   const std::string m_triggerBit;
0047   const std::vector<int> m_bunchCrossings;
0048   std::vector<int> m_triggerPattern;
0049   const unsigned int m_daqPartitions;
0050   unsigned int m_triggerNumber;
0051   bool m_triggerAlgo;
0052   bool m_triggerMasked;
0053   const bool m_ignoreL1Mask;
0054   const bool m_invert;
0055   const bool m_throw;
0056 
0057   edm::ESGetToken<L1GtTriggerMenu, L1GtTriggerMenuRcd> const m_l1GtTriggerMenuToken;
0058   edm::ESGetToken<L1GtTriggerMask, L1GtTriggerMaskAlgoTrigRcd> const m_l1GtTriggerMaskAlgoTrigRcdToken;
0059   edm::ESGetToken<L1GtTriggerMask, L1GtTriggerMaskTechTrigRcd> const m_l1GtTriggerMaskTechTrigRcdToken;
0060 
0061   edm::ESWatcher<L1GtTriggerMenuRcd> m_watchL1Menu;
0062   edm::ESWatcher<L1GtTriggerMaskAlgoTrigRcd> m_watchPhysicsMask;
0063   edm::ESWatcher<L1GtTriggerMaskTechTrigRcd> m_watchTechnicalMask;
0064 };
0065 
0066 #include "FWCore/Framework/interface/EventSetup.h"
0067 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0068 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
0069 #include "CondFormats/L1TObjects/interface/L1GtTriggerMask.h"
0070 
0071 //
0072 // constructors and destructor
0073 //
0074 HLTLevel1Pattern::HLTLevel1Pattern(const edm::ParameterSet& config)
0075     : m_gtReadoutRecord(config.getParameter<edm::InputTag>("L1GtReadoutRecordTag")),
0076       m_gtReadoutRecordToken(consumes<L1GlobalTriggerReadoutRecord>(m_gtReadoutRecord)),
0077       m_triggerBit(config.getParameter<std::string>("triggerBit")),
0078       m_bunchCrossings(config.getParameter<std::vector<int> >("bunchCrossings")),
0079       m_triggerPattern(m_bunchCrossings.size(), false),
0080       m_daqPartitions(config.getParameter<unsigned int>("daqPartitions")),
0081       m_triggerNumber(0),
0082       m_triggerAlgo(true),
0083       m_triggerMasked(false),
0084       m_ignoreL1Mask(config.getParameter<bool>("ignoreL1Mask")),
0085       m_invert(config.getParameter<bool>("invert")),
0086       m_throw(config.getParameter<bool>("throw")),
0087       m_l1GtTriggerMenuToken(esConsumes()),
0088       m_l1GtTriggerMaskAlgoTrigRcdToken(esConsumes()),
0089       m_l1GtTriggerMaskTechTrigRcdToken(esConsumes()) {
0090   std::vector<int> pattern(config.getParameter<std::vector<int> >("triggerPattern"));
0091   if (pattern.size() != m_bunchCrossings.size())
0092     throw cms::Exception("Configuration") << "\"bunchCrossings\" and \"triggerPattern\" parameters do not match";
0093 
0094   for (unsigned int i = 0; i < pattern.size(); ++i)
0095     m_triggerPattern[i] = (bool)pattern[i];
0096 }
0097 
0098 HLTLevel1Pattern::~HLTLevel1Pattern() = default;
0099 
0100 void HLTLevel1Pattern::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0101   edm::ParameterSetDescription desc;
0102   desc.add<edm::InputTag>("L1GtReadoutRecordTag", edm::InputTag("hltGtDigis"));
0103   desc.add<std::string>("triggerBit", "L1Tech_RPC_TTU_pointing_Cosmics.v0");
0104   {
0105     std::vector<int> temp1;
0106     temp1.reserve(5);
0107     temp1.push_back(-2);
0108     temp1.push_back(-1);
0109     temp1.push_back(0);
0110     temp1.push_back(1);
0111     temp1.push_back(2);
0112     desc.add<std::vector<int> >("bunchCrossings", temp1);
0113   }
0114   desc.add<unsigned int>("daqPartitions", 1);
0115   desc.add<bool>("ignoreL1Mask", false);
0116   desc.add<bool>("invert", false);
0117   desc.add<bool>("throw", true);
0118   {
0119     std::vector<int> temp1;
0120     temp1.reserve(5);
0121     temp1.push_back(1);
0122     temp1.push_back(1);
0123     temp1.push_back(1);
0124     temp1.push_back(0);
0125     temp1.push_back(0);
0126     desc.add<std::vector<int> >("triggerPattern", temp1);
0127   }
0128   descriptions.add("hltLevel1Pattern", desc);
0129 }
0130 
0131 //
0132 // member functions
0133 //
0134 
0135 // ------------ method called to produce the data  ------------
0136 bool HLTLevel1Pattern::filter(edm::Event& event, const edm::EventSetup& setup) {
0137   // determine the L1 algo or tech bit to use
0138   if (m_watchL1Menu.check(setup)) {
0139     auto const& h_menu = setup.getHandle(m_l1GtTriggerMenuToken);
0140     // look for an Algo L1 bit
0141     const AlgorithmMap& algoMap = h_menu->gtAlgorithmAliasMap();
0142     const AlgorithmMap& techMap = h_menu->gtTechnicalTriggerMap();
0143     AlgorithmMap::const_iterator entry;
0144     if ((entry = algoMap.find(m_triggerBit)) != algoMap.end()) {
0145       m_triggerAlgo = true;
0146       m_triggerNumber = entry->second.algoBitNumber();
0147     } else if ((entry = techMap.find(m_triggerBit)) != techMap.end()) {
0148       m_triggerAlgo = false;
0149       m_triggerNumber = entry->second.algoBitNumber();
0150     } else {
0151       if (m_throw) {
0152         throw cms::Exception("Configuration")
0153             << "requested L1 trigger \"" << m_triggerBit << "\" does not exist in the current L1 menu";
0154       } else {
0155         return m_invert;
0156       }
0157     }
0158   }
0159 
0160   if (m_triggerAlgo) {
0161     // check the L1 algorithms mask
0162     //  - mask & partition == part. --> fully masked
0163     //  - mask & partition == 0x00  --> fully unmasked
0164     //  - mask & partition != part. --> unmasked in some partitions, consider as unmasked
0165     if (m_watchPhysicsMask.check(setup)) {
0166       auto const& h_mask = setup.getHandle(m_l1GtTriggerMaskAlgoTrigRcdToken);
0167       m_triggerMasked = ((h_mask->gtTriggerMask()[m_triggerNumber] & m_daqPartitions) == m_daqPartitions);
0168     }
0169   } else {
0170     // check the L1 technical triggers mask
0171     //  - mask & partition == part. --> fully masked
0172     //  - mask & partition == 0x00  --> fully unmasked
0173     //  - mask & partition != part. --> unmasked in some partitions, consider as unmasked
0174     if (m_watchTechnicalMask.check(setup)) {
0175       auto const& h_mask = setup.getHandle(m_l1GtTriggerMaskTechTrigRcdToken);
0176       m_triggerMasked = ((h_mask->gtTriggerMask()[m_triggerNumber] & m_daqPartitions) == m_daqPartitions);
0177     }
0178   }
0179 
0180   // is the L1 trigger masked ?
0181   if (not m_ignoreL1Mask and m_triggerMasked)
0182     return m_invert;
0183 
0184   // access the L1 decisions
0185   edm::Handle<L1GlobalTriggerReadoutRecord> h_gtReadoutRecord;
0186   event.getByToken(m_gtReadoutRecordToken, h_gtReadoutRecord);
0187 
0188   // check the L1 algorithms results
0189   for (unsigned int i = 0; i < m_bunchCrossings.size(); ++i) {
0190     int bx = m_bunchCrossings[i];
0191     const std::vector<bool>& word =
0192         (m_triggerAlgo) ? h_gtReadoutRecord->decisionWord(bx) : h_gtReadoutRecord->technicalTriggerWord(bx);
0193     if (word.empty() or m_triggerNumber >= word.size())
0194       // L1 results not available, bail out
0195       return m_invert;
0196     bool result = word[m_triggerNumber];
0197     if (result != m_triggerPattern[i])
0198       // comparison failed, bail out
0199       return m_invert;
0200   }
0201 
0202   // comparison successful
0203   return not m_invert;
0204 }
0205 
0206 // define as a framework plugin
0207 #include "FWCore/Framework/interface/MakerMacros.h"
0208 DEFINE_FWK_MODULE(HLTLevel1Pattern);