Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:03

0001 /**
0002  * \class L1GtPatternGenerator
0003  * 
0004  * 
0005  * Description: see header file.  
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *   
0010  * \author: Thomas Themel - HEPHY Vienna
0011  * 
0012  *
0013  */
0014 
0015 // this class header
0016 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtPatternGenerator.h"
0017 
0018 // system include files
0019 #include <memory>
0020 #include <iomanip>
0021 #include <fstream>
0022 
0023 // user include files
0024 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctCollections.h"
0025 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctHtMiss.h"
0026 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTCand.h"
0027 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuRegionalCand.h"
0028 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0029 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
0030 #include "FWCore/Framework/interface/ESHandle.h"
0031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0032 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtUtils.h"
0033 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtPatternMap.h"
0034 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtPatternWriter.h"
0035 
0036 // constructor
0037 L1GtPatternGenerator::L1GtPatternGenerator(const edm::ParameterSet& parSet) {
0038   // input tags for trigger records
0039   m_gctTag = parSet.getParameter<edm::InputTag>("GctInputTag");
0040   m_gmtTag = parSet.getParameter<edm::InputTag>("GmtInputTag");
0041   m_gtTag = parSet.getParameter<edm::InputTag>("GtInputTag");
0042   m_dtTag = parSet.getParameter<edm::InputTag>("DtInputTag");
0043   m_cscTag = parSet.getParameter<edm::InputTag>("CscInputTag");
0044   m_rpcbTag = parSet.getParameter<edm::InputTag>("RpcbInputTag");
0045   m_rpcfTag = parSet.getParameter<edm::InputTag>("RpcfInputTag");
0046 
0047   // output formatting stuff
0048   m_header = parSet.getParameter<std::string>("PatternFileHeader");
0049   m_footer = parSet.getParameter<std::string>("PatternFileFooter");
0050   m_columnNames = parSet.getParameter<std::vector<std::string> >("PatternFileColumns");
0051   m_columnLengths = parSet.getParameter<std::vector<uint32_t> >("PatternFileLengths");
0052   m_columnDefaults = parSet.getParameter<std::vector<uint32_t> >("PatternFileDefaultValues");
0053   m_fileName = parSet.getParameter<std::string>("PatternFileName");
0054   m_bx = parSet.getParameter<std::vector<int> >("bx");
0055   m_debug = parSet.getParameter<bool>("DebugOutput");
0056 
0057   if (m_columnLengths.size() != m_columnNames.size()) {
0058     edm::LogWarning("L1GtPatternGenerator")
0059         << "Length of PatternFileColumns does not match length of PatternFileLenghts, " << m_columnNames.size()
0060         << " vs " << m_columnLengths.size() << std::endl;
0061   }
0062 
0063   LogDebug("L1GtPatternGenerator") << "\nL1 GCT  record:            " << m_gctTag
0064                                    << "\nL1 GMT record:             " << m_gmtTag
0065                                    << "\nL1 GT record:              " << m_gtTag << std::endl;
0066 }
0067 
0068 // destructor
0069 L1GtPatternGenerator::~L1GtPatternGenerator() {}
0070 
0071 // local helper functions
0072 
0073 /** Actual data extraction. The template parameters are neccessary because we have to handle
0074     multiple unrelated record types and call member functions of varying return type, but note
0075     that they don't need to be specified in practice because the rawFunctionPtr parameter defines
0076     them anyway. 
0077 
0078     @param iEvent          The event to get the records from.
0079     @param allPatterns     Destination object
0080     @param label           First half of the input tag that identifies our source in the event
0081     @param instance        Second half of the input tag that identifies our source in the event
0082     @param rawFunctionPtr  Pointer-to-member-function that specifies a getter function that extracts
0083                            the information we want from the record object. 
0084     @param prefix          The column name prefix that defines how the columns in the pattern map will
0085                            be named (@see L1GtPatternLine::push)
0086     @param packingFunction an optional function that the raw value is passed through befor it is 
0087                            added to the pattern line
0088 */
0089 template <class TRecord, typename TResult>
0090 static void extractRecordData(const edm::Event& iEvent,
0091                               L1GtPatternMap& allPatterns,
0092                               const std::string& label,
0093                               const std::string& instance,
0094                               TResult (TRecord::*rawFunctionPtr)() const,
0095                               const std::string& prefix,
0096                               uint32_t (*packingFunction)(uint32_t) = nullptr) {
0097   // Extract record from event.
0098   edm::Handle<std::vector<TRecord> > handle;
0099   iEvent.getByLabel(label, instance, handle);
0100 
0101   if (!handle.isValid()) {
0102     throw cms::Exception(__func__) << "Failed to extract record of type " << typeid(TRecord).name() << " labeled "
0103                                    << label << ", instance " << instance;
0104   }
0105 
0106   edm::EventNumber_t eventNr = iEvent.id().event();
0107 
0108   // Then loop over collection and add each event to the map.
0109   for (typename std::vector<TRecord>::const_iterator it = handle->begin(); it != handle->end(); ++it) {
0110     int bx = it->bx();
0111     L1GtPatternLine& line = allPatterns.getLine(eventNr, bx);
0112     uint32_t value = ((*it).*rawFunctionPtr)();
0113     if (packingFunction != nullptr) {
0114       value = packingFunction(value);
0115     }
0116 
0117     line.push(prefix, value);
0118   }
0119 }
0120 
0121 /*** Convert a vector of bools into a vector of uint32_ts. Probably
0122      optimizable, but let's just trust that it doesn't matter... */
0123 static std::vector<uint32_t> chopWords(const std::vector<bool>& aWord) {
0124   std::vector<uint32_t> result;
0125 
0126   result.resize((aWord.size() + 31) / 32, 0);
0127 
0128   for (unsigned i = 0; i < aWord.size(); ++i) {
0129     result[i / 32] |= aWord[i] << (i % 32);
0130   }
0131 
0132   return result;
0133 }
0134 
0135 /** Split a vector<bool> of arbitrary size into uint32_t chunks and add them to a
0136     pattern file line with the given prefix.
0137 */
0138 static void extractGlobalTriggerWord(const std::vector<bool> input, L1GtPatternLine& line, const std::string& prefix) {
0139   std::vector<uint32_t> resultWords = chopWords(input);
0140 
0141   // add in reverse order, so that higher-order words have lower indices
0142   // (like in "natural" number representation) (10 -> digit1=1 digit2=0)
0143   for (unsigned i = resultWords.size(); i > 0; --i) {
0144     line.push(prefix, resultWords[i - 1]);
0145   }
0146 }
0147 
0148 /** Bits 8..15 (5 bits Pt, 3 bits quality) need to be inverted on the GMT inputs.
0149  *  See http://wwwhephy.oeaw.ac.at/p3w/cms/trigger/globalMuonTrigger/notes/in04_022.pdf
0150  */
0151 uint32_t L1GtPatternGenerator::packRegionalMuons(uint32_t rawData) {
0152   uint32_t invertMask = 0x0000FF00;
0153   uint32_t toKeep = rawData & (~invertMask);
0154   return toKeep | (~rawData & invertMask);
0155 }
0156 
0157 // member functions
0158 void L1GtPatternGenerator::extractGlobalTriggerData(const edm::Event& iEvent, L1GtPatternMap& patterns) {
0159   // extract global trigger readout record
0160   edm::Handle<L1GlobalTriggerReadoutRecord> handle;
0161   iEvent.getByLabel(m_gtTag, handle);
0162 
0163   // continue if it's present
0164   if (!handle.isValid()) {
0165     throw cms::Exception(__func__) << "Failed to extract GT readout record labeled " << m_gtTag.label() << ", instance "
0166                                    << m_gtTag.instance();
0167   }
0168 
0169   edm::EventNumber_t eventNr = iEvent.id().event();
0170 
0171   // for each FDL word...
0172   const std::vector<L1GtFdlWord>& fdlWords = handle->gtFdlVector();
0173   for (std::vector<L1GtFdlWord>::const_iterator it = fdlWords.begin(); it != fdlWords.end(); ++it) {
0174     // extract relevant data
0175     int bx = it->bxInEvent();
0176 
0177     // find matching pattern file line
0178     L1GtPatternLine& line = patterns.getLine(eventNr, bx);
0179 
0180     extractGlobalTriggerWord(it->gtDecisionWord(), line, "gtDecision");
0181     extractGlobalTriggerWord(it->gtDecisionWordExtended(), line, "gtDecisionExt");
0182     extractGlobalTriggerWord(it->gtTechnicalTriggerWord(), line, "gtTechTrigger");
0183 
0184     line.push("gtFinalOr", it->finalOR());
0185   }
0186 }
0187 
0188 /** The mapping from hfBitCounts/hfRingEtSums raw data to the PSBs is non-trivial, see
0189  *  http://wwwhephy.oeaw.ac.at/p3w/electronic1/GlobalTrigger/doc/InterfaceDesc/update_CMS_NOTE_2002_069.pdf
0190  */
0191 void L1GtPatternGenerator::packHfRecords(const std::string& resultName, L1GtPatternMap& allPatterns) {
0192   // iterate over each pattern line
0193   for (L1GtPatternMap::LineMap::iterator it = allPatterns.begin(); it != allPatterns.end(); ++it) {
0194     // Get the HF bit counts and ring sums
0195     uint32_t counts = it->second.get("hfBitCounts1");
0196     uint32_t sums = it->second.get("hfRingEtSums1");
0197 
0198     // Bits 0..11 -> 4 bit counts
0199     uint32_t hfPsbValue = (counts & 0xFFF) |
0200                           // Bit 12..14 ring 1 pos. rap. HF Et sum
0201                           (sums & 0x7) << 12 |
0202                           // Bits 16.. rest of the ET sums
0203                           (sums >> 3) << 16;
0204     // TODO: Spec states non-data values for Bits 15, 31, 47 and 63.
0205 
0206     // Export computed value to pattern writer. */
0207     it->second.push(resultName, hfPsbValue);
0208   }
0209 }
0210 
0211 /** Analyze each event: 
0212     - Extract the input records that interest us from the event
0213     - Split them into pattern file lines according to their bx number
0214     - Format the lines and write them to the file. 
0215 */
0216 void L1GtPatternGenerator::analyze(const edm::Event& iEvent, const edm::EventSetup& evSetup) {
0217   // debug information
0218   const unsigned int runNumber = iEvent.run();
0219   const unsigned int lsNumber = iEvent.luminosityBlock();
0220   const unsigned int eventNumber = iEvent.id().event();
0221 
0222   LogTrace("L1GtPatternGenerator") << "\n\nL1GtPatternGenerator::analyze: Run: " << runNumber << " LS: " << lsNumber
0223                                    << " Event: " << eventNumber << "\n\n"
0224                                    << std::endl;
0225 
0226   L1GtPatternMap allPatterns;
0227 
0228   // GMT muon candidates
0229   extractRecordData(iEvent, allPatterns, m_gmtTag.label(), m_gmtTag.instance(), &L1MuGMTCand::getDataWord, "gmtMuon");
0230 
0231   // regional muon candidates
0232   extractRecordData(iEvent,
0233                     allPatterns,
0234                     m_cscTag.label(),
0235                     m_cscTag.instance(),
0236                     &L1MuRegionalCand::getDataWord,
0237                     "cscMuon",
0238                     packRegionalMuons);
0239   extractRecordData(iEvent,
0240                     allPatterns,
0241                     m_dtTag.label(),
0242                     m_dtTag.instance(),
0243                     &L1MuRegionalCand::getDataWord,
0244                     "dtMuon",
0245                     packRegionalMuons);
0246   extractRecordData(iEvent,
0247                     allPatterns,
0248                     m_rpcfTag.label(),
0249                     m_rpcfTag.instance(),
0250                     &L1MuRegionalCand::getDataWord,
0251                     "fwdMuon",
0252                     packRegionalMuons);
0253   extractRecordData(iEvent,
0254                     allPatterns,
0255                     m_rpcbTag.label(),
0256                     m_rpcbTag.instance(),
0257                     &L1MuRegionalCand::getDataWord,
0258                     "brlMuon",
0259                     packRegionalMuons);
0260 
0261   // GCT objects
0262   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "nonIsoEm", &L1GctEmCand::raw, "gctEm");
0263   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "isoEm", &L1GctEmCand::raw, "gctIsoEm");
0264   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctEtMiss::et, "etMiss");
0265   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctEtMiss::phi, "etMissPhi");
0266   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctHtMiss::raw, "htMiss");
0267   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctEtHad::raw, "etHad");
0268   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctEtTotal::raw, "etTotal");
0269   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "cenJets", &L1GctJetCand::raw, "cenJet");
0270   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "forJets", &L1GctJetCand::raw, "forJet");
0271   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "tauJets", &L1GctJetCand::raw, "tauJet");
0272   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctHFBitCounts::raw, "hfBitCounts");
0273   extractRecordData(iEvent, allPatterns, m_gctTag.label(), "", &L1GctHFRingEtSums::raw, "hfRingEtSums");
0274 
0275   // Post processing:
0276   // HFBitCounts/HFRingEtSums need to be mangled to PSB values
0277   packHfRecords("hfPsbValue", allPatterns);
0278 
0279   // GT objects
0280   extractGlobalTriggerData(iEvent, allPatterns);
0281 
0282   // Output
0283   m_writer->writePatterns(allPatterns);
0284 }
0285 
0286 /** Method called once each job just before starting event loop.
0287     - Initialize the output file and the writer object. 
0288 */
0289 void L1GtPatternGenerator::beginJob() {
0290   m_fileStream.open(m_fileName.c_str());
0291 
0292   if (!m_fileStream) {
0293     edm::LogError("L1GtPatternGenerator") << "Failed to open output file " << m_fileName;
0294   }
0295 
0296   m_writer = std::make_unique<L1GtPatternWriter>(
0297       m_fileStream, m_header, m_footer, m_columnNames, m_columnLengths, m_columnDefaults, m_bx, m_debug);
0298 }
0299 
0300 /** Method called once each job just after ending the event loop.
0301     - Close the output file stream.
0302  */
0303 void L1GtPatternGenerator::endJob() {
0304   m_writer->close();
0305   m_fileStream.close();
0306 }