Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:11:30

0001 /**
0002  * \class L1GlobalTriggerFDL
0003  *
0004  *
0005  * Description: Final Decision Logic board.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  * \author: M. Fierro            - HEPHY Vienna - ORCA version
0011  * \author: Vasile Mihai Ghete   - HEPHY Vienna - CMSSW version
0012  *
0013  *
0014  */
0015 
0016 // this class header
0017 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerFDL.h"
0018 
0019 // system include files
0020 #include <iostream>
0021 
0022 // user include files
0023 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
0024 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
0025 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
0026 
0027 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
0028 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0029 
0030 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerGTL.h"
0031 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerPSB.h"
0032 
0033 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0035 
0036 #include "FWCore/Framework/interface/Event.h"
0037 
0038 #include "CondFormats/L1TObjects/interface/L1GtBoard.h"
0039 #include "CondFormats/L1TObjects/interface/L1GtFwd.h"
0040 
0041 // forward declarations
0042 
0043 // constructor
0044 L1GlobalTriggerFDL::L1GlobalTriggerFDL()
0045     :  // logical switches
0046       m_firstEv(true),
0047       m_firstEvLumiSegment(true),
0048       m_firstEvRun(true),
0049       m_isDebugEnabled(edm::isDebugEnabled()) {
0050   // create empty FDL word
0051   m_gtFdlWord = new L1GtFdlWord();
0052 
0053   // can not reserve memory here for prescale counters - no access to EventSetup
0054 }
0055 
0056 // destructor
0057 L1GlobalTriggerFDL::~L1GlobalTriggerFDL() {
0058   reset();
0059   delete m_gtFdlWord;
0060 }
0061 
0062 // Operations
0063 
0064 // run FDL
0065 void L1GlobalTriggerFDL::run(edm::Event &iEvent,
0066                              const std::vector<int> &prescaleFactorsAlgoTrig,
0067                              const std::vector<int> &prescaleFactorsTechTrig,
0068                              const std::vector<unsigned int> &triggerMaskAlgoTrig,
0069                              const std::vector<unsigned int> &triggerMaskTechTrig,
0070                              const std::vector<unsigned int> &triggerMaskVetoAlgoTrig,
0071                              const std::vector<unsigned int> &triggerMaskVetoTechTrig,
0072                              const std::vector<L1GtBoard> &boardMaps,
0073                              const int totalBxInEvent,
0074                              const int iBxInEvent,
0075                              const unsigned int numberPhysTriggers,
0076                              const unsigned int numberTechnicalTriggers,
0077                              const unsigned int numberDaqPartitions,
0078                              const L1GlobalTriggerGTL *ptrGTL,
0079                              const L1GlobalTriggerPSB *ptrPSB,
0080                              const int pfAlgoSetIndex,
0081                              const int pfTechSetIndex,
0082                              const bool algorithmTriggersUnprescaled,
0083                              const bool algorithmTriggersUnmasked,
0084                              const bool technicalTriggersUnprescaled,
0085                              const bool technicalTriggersUnmasked,
0086                              const bool technicalTriggersVetoUnmasked) {
0087   // FIXME get rid of bitset in GTL in order to use only EventSetup
0088   const unsigned int numberPhysTriggersSet = L1GlobalTriggerReadoutSetup::NumberPhysTriggers;
0089 
0090   // get gtlDecisionWord from GTL
0091   std::bitset<numberPhysTriggersSet> gtlDecisionWord = ptrGTL->getAlgorithmOR();
0092 
0093   // convert decision word from std::bitset to std::vector<bool>
0094   DecisionWord algoDecisionWord(numberPhysTriggers);
0095 
0096   for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
0097     bool bitValue = gtlDecisionWord.test(iBit);
0098     algoDecisionWord[iBit] = bitValue;
0099   }
0100 
0101   // prescale counters are reset at the beginning of the luminosity segment
0102 
0103   if (m_firstEv) {
0104     // prescale counters: numberPhysTriggers counters per bunch cross
0105     m_prescaleCounterAlgoTrig.reserve(numberPhysTriggers * totalBxInEvent);
0106 
0107     for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
0108       m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig);
0109     }
0110 
0111     // prescale counters: numberTechnicalTriggers counters per bunch cross
0112     m_prescaleCounterTechTrig.reserve(numberTechnicalTriggers * totalBxInEvent);
0113 
0114     for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
0115       m_prescaleCounterTechTrig.push_back(prescaleFactorsTechTrig);
0116     }
0117 
0118     m_firstEv = false;
0119   }
0120 
0121   // TODO FIXME find the beginning of the luminosity segment
0122   if (m_firstEvLumiSegment) {
0123     m_prescaleCounterAlgoTrig.clear();
0124     for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
0125       m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig);
0126     }
0127 
0128     m_prescaleCounterTechTrig.clear();
0129     for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
0130       m_prescaleCounterTechTrig.push_back(prescaleFactorsTechTrig);
0131     }
0132 
0133     m_firstEvLumiSegment = false;
0134   }
0135 
0136   // prescale the algorithm, if necessary
0137 
0138   // iBxInEvent is ... -2 -1 0 1 2 ... while counters are 0 1 2 3 4 ...
0139   int inBxInEvent = totalBxInEvent / 2 + iBxInEvent;
0140 
0141   for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
0142     if ((!algorithmTriggersUnprescaled) && (prescaleFactorsAlgoTrig.at(iBit) != 1)) {
0143       bool bitValue = algoDecisionWord.at(iBit);
0144       if (bitValue) {
0145         (m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit))--;
0146         if (m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit) == 0) {
0147           // bit already true in algoDecisionWord, just reset counter
0148           m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit) = prescaleFactorsAlgoTrig.at(iBit);
0149 
0150           // LogTrace("L1GlobalTrigger")
0151           //<< "\nPrescaled algorithm: " << iBit << ". Reset counter to "
0152           //<< prescaleFactorsAlgoTrig.at(iBit) << "\n"
0153           //<< std::endl;
0154 
0155         } else {
0156           // change bit to false
0157           algoDecisionWord[iBit] = false;
0158           ;
0159 
0160           // LogTrace("L1GlobalTrigger")
0161           //<< "\nPrescaled algorithm: " << iBit << ". Result set to false"
0162           //<< std::endl;
0163         }
0164       }
0165     }
0166   }
0167 
0168   // algo decision word written in the FDL readout before the trigger mask
0169   // in order to allow multiple DAQ partitions
0170 
0171   //
0172   // technical triggers
0173   //
0174 
0175   std::vector<bool> techDecisionWord = *(ptrPSB->getGtTechnicalTriggers());
0176 
0177   // prescale the technical trigger, if necessary
0178 
0179   for (unsigned int iBit = 0; iBit < numberTechnicalTriggers; ++iBit) {
0180     if ((!technicalTriggersUnprescaled) && (prescaleFactorsTechTrig.at(iBit) != 1)) {
0181       bool bitValue = techDecisionWord.at(iBit);
0182       if (bitValue) {
0183         (m_prescaleCounterTechTrig.at(inBxInEvent).at(iBit))--;
0184         if (m_prescaleCounterTechTrig.at(inBxInEvent).at(iBit) == 0) {
0185           // bit already true in techDecisionWord, just reset counter
0186           m_prescaleCounterTechTrig.at(inBxInEvent).at(iBit) = prescaleFactorsTechTrig.at(iBit);
0187 
0188           // LogTrace("L1GlobalTrigger")
0189           //<< "\nPrescaled algorithm: " << iBit << ". Reset counter to "
0190           //<< prescaleFactorsTechTrig.at(iBit) << "\n"
0191           //<< std::endl;
0192 
0193         } else {
0194           // change bit to false
0195           techDecisionWord[iBit] = false;
0196 
0197           // LogTrace("L1GlobalTrigger")
0198           //<< "\nPrescaled technical trigger: " << iBit << ". Result set to
0199           // false"
0200           //<< std::endl;
0201         }
0202       }
0203     }
0204   }
0205 
0206   // technical trigger decision word written in the FDL readout before the
0207   // trigger mask in order to allow multiple DAQ partitions
0208 
0209   //
0210   // compute the final decision word per DAQ partition
0211   //
0212 
0213   uint16_t finalOrValue = 0;
0214 
0215   for (unsigned int iDaq = 0; iDaq < numberDaqPartitions; ++iDaq) {
0216     bool daqPartitionFinalOR = false;
0217 
0218     // starts with technical trigger veto mask to minimize computation
0219     // no algorithm trigger veto mask is implemented up to now in hardware,
0220     // therefore do not implement it here
0221     bool vetoTechTrig = false;
0222 
0223     // vetoTechTrig can change only when using trigger veto masks
0224     if (!technicalTriggersVetoUnmasked) {
0225       for (unsigned int iBit = 0; iBit < numberTechnicalTriggers; ++iBit) {
0226         int triggerMaskVetoTechTrigBit = triggerMaskVetoTechTrig[iBit] & (1 << iDaq);
0227         // LogTrace("L1GlobalTrigger")
0228         //<< "\nTechnical trigger bit: " << iBit
0229         //<< " mask = " << triggerMaskVetoTechTrigBit
0230         //<< " DAQ partition " << iDaq
0231         //<< std::endl;
0232 
0233         if (triggerMaskVetoTechTrigBit && techDecisionWord[iBit]) {
0234           daqPartitionFinalOR = false;
0235           vetoTechTrig = true;
0236 
0237           // LogTrace("L1GlobalTrigger")
0238           //<< "\nVeto mask technical trigger: " << iBit
0239           // << ". FinalOR for DAQ partition " << iDaq << " set to false"
0240           //<< std::endl;
0241 
0242           break;
0243         }
0244       }
0245     }
0246 
0247     // apply algorithm and technical trigger masks only if no veto from
0248     // technical trigger
0249     if (!vetoTechTrig) {
0250       // algorithm trigger mask
0251       bool algoFinalOr = false;
0252 
0253       for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
0254         bool iBitDecision = false;
0255 
0256         int triggerMaskAlgoTrigBit = -1;
0257 
0258         if (algorithmTriggersUnmasked) {
0259           triggerMaskAlgoTrigBit = 0;
0260         } else {
0261           triggerMaskAlgoTrigBit = triggerMaskAlgoTrig[iBit] & (1 << iDaq);
0262         }
0263         // LogTrace("L1GlobalTrigger")
0264         //<< "\nAlgorithm trigger bit: " << iBit
0265         //<< " mask = " << triggerMaskAlgoTrigBit
0266         //<< " DAQ partition " << iDaq
0267         //<< std::endl;
0268 
0269         if (triggerMaskAlgoTrigBit) {
0270           iBitDecision = false;
0271 
0272           // LogTrace("L1GlobalTrigger")
0273           //<< "\nMasked algorithm trigger: " << iBit << ". Result set to false"
0274           //<< std::endl;
0275         } else {
0276           iBitDecision = algoDecisionWord[iBit];
0277         }
0278 
0279         algoFinalOr = algoFinalOr || iBitDecision;
0280       }
0281 
0282       // set the technical trigger mask: block the corresponding algorithm if
0283       // bit value is 1
0284 
0285       bool techFinalOr = false;
0286 
0287       for (unsigned int iBit = 0; iBit < numberTechnicalTriggers; ++iBit) {
0288         bool iBitDecision = false;
0289 
0290         int triggerMaskTechTrigBit = -1;
0291 
0292         if (technicalTriggersUnmasked) {
0293           triggerMaskTechTrigBit = 0;
0294         } else {
0295           triggerMaskTechTrigBit = triggerMaskTechTrig[iBit] & (1 << iDaq);
0296         }
0297         // LogTrace("L1GlobalTrigger")
0298         //<< "\nTechnical trigger bit: " << iBit
0299         //<< " mask = " << triggerMaskTechTrigBit
0300         //<< std::endl;
0301 
0302         if (triggerMaskTechTrigBit) {
0303           iBitDecision = false;
0304 
0305           // LogTrace("L1GlobalTrigger")
0306           //<< "\nMasked technical trigger: " << iBit << ". Result set to false"
0307           //<< std::endl;
0308         } else {
0309           iBitDecision = techDecisionWord[iBit];
0310         }
0311 
0312         techFinalOr = techFinalOr || iBitDecision;
0313       }
0314 
0315       daqPartitionFinalOR = algoFinalOr || techFinalOr;
0316 
0317     } else {
0318       daqPartitionFinalOR = false;  // vetoTechTrig
0319     }
0320 
0321     // push it in finalOrValue
0322     uint16_t daqPartitionFinalORValue = static_cast<uint16_t>(daqPartitionFinalOR);
0323 
0324     finalOrValue = finalOrValue | (daqPartitionFinalORValue << iDaq);
0325   }
0326 
0327   // fill everything we know in the L1GtFdlWord
0328 
0329   typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
0330   for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0331     if ((itBoard->gtBoardType() == FDL)) {
0332       m_gtFdlWord->setBoardId(itBoard->gtBoardId());
0333 
0334       // BxInEvent
0335       m_gtFdlWord->setBxInEvent(iBxInEvent);
0336 
0337       // bunch crossing
0338 
0339       // fill in emulator the same bunch crossing (12 bits - hardwired number of
0340       // bits...) and the same local bunch crossing for all boards
0341       int bxCross = iEvent.bunchCrossing();
0342       uint16_t bxCrossHw = 0;
0343       if ((bxCross & 0xFFF) == bxCross) {
0344         bxCrossHw = static_cast<uint16_t>(bxCross);
0345       } else {
0346         bxCrossHw = 0;  // Bx number too large, set to 0!
0347         if (m_verbosity) {
0348           LogDebug("L1GlobalTrigger") << "\nBunch cross number [hex] = " << std::hex << bxCross
0349                                       << "\n  larger than 12 bits. Set to 0! \n"
0350                                       << std::dec << std::endl;
0351         }
0352       }
0353 
0354       m_gtFdlWord->setBxNr(bxCrossHw);
0355 
0356       // set event number since last L1 reset generated in FDL
0357       m_gtFdlWord->setEventNr(static_cast<uint32_t>(iEvent.id().event()));
0358 
0359       // technical trigger decision word
0360       m_gtFdlWord->setGtTechnicalTriggerWord(techDecisionWord);
0361 
0362       // algorithm trigger decision word
0363       m_gtFdlWord->setGtDecisionWord(algoDecisionWord);
0364 
0365       // index of prescale factor set - technical triggers and algo
0366       m_gtFdlWord->setGtPrescaleFactorIndexTech(static_cast<uint16_t>(pfTechSetIndex));
0367       m_gtFdlWord->setGtPrescaleFactorIndexAlgo(static_cast<uint16_t>(pfAlgoSetIndex));
0368 
0369       // NoAlgo bit FIXME
0370 
0371       // finalOR
0372       m_gtFdlWord->setFinalOR(finalOrValue);
0373 
0374       // orbit number
0375       m_gtFdlWord->setOrbitNr(static_cast<uint32_t>(iEvent.orbitNumber()));
0376 
0377       // luminosity segment number
0378       m_gtFdlWord->setLumiSegmentNr(static_cast<uint16_t>(iEvent.luminosityBlock()));
0379 
0380       // local bunch crossing - set identical with absolute BxNr
0381       m_gtFdlWord->setLocalBxNr(bxCrossHw);
0382     }
0383   }
0384 }
0385 
0386 // fill the FDL block in the L1 GT DAQ record for iBxInEvent
0387 void L1GlobalTriggerFDL::fillDaqFdlBlock(const int iBxInEvent,
0388                                          const uint16_t &activeBoardsGtDaq,
0389                                          const int recordLength0,
0390                                          const int recordLength1,
0391                                          const unsigned int altNrBxBoardDaq,
0392                                          const std::vector<L1GtBoard> &boardMaps,
0393                                          L1GlobalTriggerReadoutRecord *gtDaqReadoutRecord) {
0394   typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
0395   for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0396     int iPosition = itBoard->gtPositionDaqRecord();
0397     if (iPosition > 0) {
0398       int iActiveBit = itBoard->gtBitDaqActiveBoards();
0399       bool activeBoard = false;
0400       bool writeBoard = false;
0401 
0402       int recLength = -1;
0403 
0404       if (iActiveBit >= 0) {
0405         activeBoard = activeBoardsGtDaq & (1 << iActiveBit);
0406 
0407         int altNrBxBoard = (altNrBxBoardDaq & (1 << iActiveBit)) >> iActiveBit;
0408 
0409         if (altNrBxBoard == 1) {
0410           recLength = recordLength1;
0411         } else {
0412           recLength = recordLength0;
0413         }
0414 
0415         int lowBxInEvent = (recLength + 1) / 2 - recLength;
0416         int uppBxInEvent = (recLength + 1) / 2 - 1;
0417 
0418         if ((iBxInEvent >= lowBxInEvent) && (iBxInEvent <= uppBxInEvent)) {
0419           writeBoard = true;
0420         }
0421       }
0422 
0423       if (activeBoard && writeBoard && (itBoard->gtBoardType() == FDL)) {
0424         gtDaqReadoutRecord->setGtFdlWord(*m_gtFdlWord);
0425       }
0426     }
0427   }
0428 }
0429 
0430 // fill the FDL block in the L1 GT EVM record for iBxInEvent
0431 void L1GlobalTriggerFDL::fillEvmFdlBlock(const int iBxInEvent,
0432                                          const uint16_t &activeBoardsGtEvm,
0433                                          const int recordLength0,
0434                                          const int recordLength1,
0435                                          const unsigned int altNrBxBoardEvm,
0436                                          const std::vector<L1GtBoard> &boardMaps,
0437                                          L1GlobalTriggerEvmReadoutRecord *gtEvmReadoutRecord) {
0438   typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
0439   for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
0440     int iPosition = itBoard->gtPositionEvmRecord();
0441     if (iPosition > 0) {
0442       int iActiveBit = itBoard->gtBitEvmActiveBoards();
0443       bool activeBoard = false;
0444 
0445       if (iActiveBit >= 0) {
0446         activeBoard = activeBoardsGtEvm & (1 << iActiveBit);
0447       }
0448 
0449       if (activeBoard && (itBoard->gtBoardType() == FDL)) {
0450         gtEvmReadoutRecord->setGtFdlWord(*m_gtFdlWord);
0451       }
0452     }
0453   }
0454 }
0455 
0456 // clear FDL
0457 void L1GlobalTriggerFDL::reset() {
0458   m_gtFdlWord->reset();
0459 
0460   // do NOT reset the prescale counters
0461 }