CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/L1Trigger/GlobalTrigger/src/L1GlobalTriggerFDL.cc

Go to the documentation of this file.
00001 
00018 // this class header
00019 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerFDL.h"
00020 
00021 // system include files
00022 #include <iostream>
00023 
00024 // user include files
00025 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
00026 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
00027 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
00028 
00029 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
00030 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
00031 
00032 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerGTL.h"
00033 #include "L1Trigger/GlobalTrigger/interface/L1GlobalTriggerPSB.h"
00034 
00035 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00036 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00037 
00038 #include "FWCore/Framework/interface/Event.h"
00039 
00040 #include "CondFormats/L1TObjects/interface/L1GtFwd.h"
00041 #include "CondFormats/L1TObjects/interface/L1GtBoard.h"
00042 
00043 
00044 // forward declarations
00045 
00046 
00047 // constructor
00048 L1GlobalTriggerFDL::L1GlobalTriggerFDL() :
00049     // logical switches
00050     m_firstEv(true),
00051     m_firstEvLumiSegment(true),
00052     m_firstEvRun(true),
00053     m_isDebugEnabled(edm::isDebugEnabled())
00054 {
00055 
00056     // create empty FDL word
00057     m_gtFdlWord = new L1GtFdlWord();
00058 
00059 
00060     // can not reserve memory here for prescale counters - no access to EventSetup
00061 
00062 }
00063 
00064 // destructor
00065 L1GlobalTriggerFDL::~L1GlobalTriggerFDL()
00066 {
00067 
00068     reset();
00069     delete m_gtFdlWord;
00070 
00071 }
00072 
00073 // Operations
00074 
00075 // run FDL
00076 void L1GlobalTriggerFDL::run(
00077     edm::Event& iEvent,
00078     const std::vector<int>& prescaleFactorsAlgoTrig,
00079     const std::vector<int>& prescaleFactorsTechTrig,
00080     const std::vector<unsigned int>& triggerMaskAlgoTrig,
00081     const std::vector<unsigned int>& triggerMaskTechTrig,
00082     const std::vector<unsigned int>& triggerMaskVetoAlgoTrig,
00083     const std::vector<unsigned int>& triggerMaskVetoTechTrig,
00084     const std::vector<L1GtBoard>& boardMaps,
00085     const int totalBxInEvent,
00086     const int iBxInEvent,
00087     const unsigned int numberPhysTriggers, const unsigned int numberTechnicalTriggers,
00088     const unsigned int numberDaqPartitions,
00089     const L1GlobalTriggerGTL* ptrGTL,
00090     const L1GlobalTriggerPSB* ptrPSB,
00091     const int pfAlgoSetIndex,
00092     const int pfTechSetIndex)
00093 {
00094 
00095     // FIXME get rid of bitset in GTL in order to use only EventSetup
00096     const unsigned int numberPhysTriggersSet =
00097         L1GlobalTriggerReadoutSetup::NumberPhysTriggers;
00098 
00099     // get gtlDecisionWord from GTL
00100     std::bitset<numberPhysTriggersSet> gtlDecisionWord = ptrGTL->getAlgorithmOR();
00101 
00102     // convert decision word from std::bitset to std::vector<bool>
00103     DecisionWord algoDecisionWord(numberPhysTriggers);
00104 
00105     for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
00106 
00107         bool bitValue = gtlDecisionWord.test( iBit );
00108         algoDecisionWord[ iBit ] = bitValue;
00109     }
00110 
00111     // prescale counters are reset at the beginning of the luminosity segment
00112 
00113     if (m_firstEv) {
00114 
00115         // prescale counters: numberPhysTriggers counters per bunch cross
00116         m_prescaleCounterAlgoTrig.reserve(numberPhysTriggers*totalBxInEvent);
00117 
00118         for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
00119 
00120             m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig);
00121         }
00122 
00123         // prescale counters: numberTechnicalTriggers counters per bunch cross
00124         m_prescaleCounterTechTrig.reserve(numberTechnicalTriggers*totalBxInEvent);
00125 
00126         for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
00127 
00128             m_prescaleCounterTechTrig.push_back(prescaleFactorsTechTrig);
00129         }
00130 
00131         m_firstEv = false;
00132     }
00133 
00134     // TODO FIXME find the beginning of the luminosity segment
00135     if (m_firstEvLumiSegment) {
00136 
00137         m_prescaleCounterAlgoTrig.clear();
00138         for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
00139             m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig);
00140         }
00141 
00142         m_prescaleCounterTechTrig.clear();
00143         for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) {
00144             m_prescaleCounterTechTrig.push_back(prescaleFactorsTechTrig);
00145         }
00146 
00147         m_firstEvLumiSegment = false;
00148 
00149     }
00150 
00151 
00152     // prescale the algorithm, if necessary
00153 
00154     // iBxInEvent is ... -2 -1 0 1 2 ... while counters are 0 1 2 3 4 ...
00155     int inBxInEvent =  totalBxInEvent/2 + iBxInEvent;
00156 
00157     for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
00158 
00159         if (prescaleFactorsAlgoTrig.at(iBit) != 1) {
00160 
00161             bool bitValue = algoDecisionWord.at( iBit );
00162             if (bitValue) {
00163 
00164                 (m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit))--;
00165                 if (m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit) == 0) {
00166 
00167                     // bit already true in algoDecisionWord, just reset counter
00168                     m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit) =
00169                         prescaleFactorsAlgoTrig.at(iBit);
00170 
00171                     //LogTrace("L1GlobalTriggerFDL")
00172                     //<< "\nPrescaled algorithm: " << iBit << ". Reset counter to "
00173                     //<< prescaleFactorsAlgoTrig.at(iBit) << "\n"
00174                     //<< std::endl;
00175 
00176                 } else {
00177 
00178                     // change bit to false
00179                     algoDecisionWord[iBit] = false;;
00180 
00181                     //LogTrace("L1GlobalTriggerFDL")
00182                     //<< "\nPrescaled algorithm: " << iBit << ". Result set to false"
00183                     //<< std::endl;
00184 
00185                 }
00186             }
00187         }
00188     }
00189 
00190     // algo decision word written in the FDL readout before the trigger mask
00191     // in order to allow multiple DAQ partitions
00192 
00193     //
00194     // technical triggers
00195     //
00196 
00197     std::vector<bool> techDecisionWord = *(ptrPSB->getGtTechnicalTriggers());
00198 
00199     // prescale the technical trigger, if necessary
00200 
00201     for (unsigned int iBit = 0; iBit < numberTechnicalTriggers; ++iBit) {
00202 
00203         if (prescaleFactorsTechTrig.at(iBit) != 1) {
00204 
00205             bool bitValue = techDecisionWord.at( iBit );
00206             if (bitValue) {
00207 
00208                 (m_prescaleCounterTechTrig.at(inBxInEvent).at(iBit))--;
00209                 if (m_prescaleCounterTechTrig.at(inBxInEvent).at(iBit) == 0) {
00210 
00211                     // bit already true in techDecisionWord, just reset counter
00212                     m_prescaleCounterTechTrig.at(inBxInEvent).at(iBit) =
00213                         prescaleFactorsTechTrig.at(iBit);
00214 
00215                     //LogTrace("L1GlobalTriggerFDL")
00216                     //<< "\nPrescaled algorithm: " << iBit << ". Reset counter to "
00217                     //<< prescaleFactorsTechTrig.at(iBit) << "\n"
00218                     //<< std::endl;
00219 
00220                 } else {
00221 
00222                     // change bit to false
00223                     techDecisionWord[iBit] = false;
00224 
00225                     //LogTrace("L1GlobalTriggerFDL")
00226                     //<< "\nPrescaled technical trigger: " << iBit << ". Result set to false"
00227                     //<< std::endl;
00228 
00229                 }
00230             }
00231         }
00232     }
00233 
00234     // technical trigger decision word written in the FDL readout before the trigger mask
00235     // in order to allow multiple DAQ partitions
00236 
00237     //
00238     // compute the final decision word per DAQ partition
00239     //
00240 
00241     boost::uint16_t finalOrValue = 0;
00242 
00243     for (unsigned int iDaq = 0; iDaq < numberDaqPartitions; ++iDaq) {
00244 
00245         bool daqPartitionFinalOR = false;
00246 
00247         // starts with technical trigger veto mask to minimize computation
00248         // no algorithm trigger veto mask is implemented up to now in hardware,
00249         // therefore do not implement it here
00250         bool vetoTechTrig = false;
00251 
00252         for (unsigned int iBit = 0; iBit < numberTechnicalTriggers; ++iBit) {
00253 
00254             int triggerMaskVetoTechTrigBit =
00255                 triggerMaskVetoTechTrig[iBit] & (1 << iDaq);
00256             //LogTrace("L1GlobalTriggerFDL")
00257             //<< "\nTechnical trigger bit: " << iBit
00258             //<< " mask = " << triggerMaskVetoTechTrigBit
00259             //<< " DAQ partition " << iDaq
00260             //<< std::endl;
00261 
00262             if (triggerMaskVetoTechTrigBit && techDecisionWord[iBit]) {
00263 
00264                 daqPartitionFinalOR = false;
00265                 vetoTechTrig = true;
00266 
00267                 //LogTrace("L1GlobalTriggerFDL")
00268                 //<< "\nVeto mask technical trigger: " << iBit
00269                 // << ". FinalOR for DAQ partition " << iDaq << " set to false"
00270                 //<< std::endl;
00271 
00272                 break;
00273             }
00274 
00275         }
00276 
00277         // apply algorithm and technical trigger masks only if no veto from technical trigger
00278         if (!vetoTechTrig) {
00279 
00280             // algorithm trigger mask
00281             bool algoFinalOr = false;
00282 
00283             for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
00284 
00285                 bool iBitDecision = false;
00286 
00287                 int triggerMaskAlgoTrigBit = triggerMaskAlgoTrig[iBit] & (1 << iDaq);
00288                 //LogTrace("L1GlobalTriggerFDL")
00289                 //<< "\nAlgorithm trigger bit: " << iBit
00290                 //<< " mask = " << triggerMaskAlgoTrigBit
00291                 //<< " DAQ partition " << iDaq
00292                 //<< std::endl;
00293 
00294                 if (triggerMaskAlgoTrigBit) {
00295                     iBitDecision = false;
00296 
00297                     //LogTrace("L1GlobalTriggerFDL")
00298                     //<< "\nMasked algorithm trigger: " << iBit << ". Result set to false"
00299                     //<< std::endl;
00300                 } else {
00301                     iBitDecision = algoDecisionWord[iBit];
00302                 }
00303 
00304                 algoFinalOr = algoFinalOr || iBitDecision;
00305 
00306             }
00307 
00308             // set the technical trigger mask: block the corresponding algorithm if bit value is 1
00309 
00310             bool techFinalOr = false;
00311 
00312             for (unsigned int iBit = 0; iBit < numberTechnicalTriggers; ++iBit) {
00313 
00314                 bool iBitDecision = false;
00315 
00316                 int triggerMaskTechTrigBit = triggerMaskTechTrig[iBit] & (1 << iDaq);
00317                 //LogTrace("L1GlobalTriggerFDL")
00318                 //<< "\nTechnical trigger bit: " << iBit
00319                 //<< " mask = " << triggerMaskTechTrigBit
00320                 //<< std::endl;
00321 
00322                 if (triggerMaskTechTrigBit) {
00323 
00324                     iBitDecision = false;
00325 
00326                     //LogTrace("L1GlobalTriggerFDL")
00327                     //<< "\nMasked technical trigger: " << iBit << ". Result set to false"
00328                     //<< std::endl;
00329                 } else {
00330                     iBitDecision = techDecisionWord[iBit];
00331                 }
00332 
00333                 techFinalOr = techFinalOr || iBitDecision;
00334             }
00335 
00336             daqPartitionFinalOR = algoFinalOr || techFinalOr;
00337 
00338         } else {
00339 
00340             daqPartitionFinalOR = false; // vetoTechTrig
00341 
00342         }
00343 
00344         // push it in finalOrValue
00345         boost::uint16_t daqPartitionFinalORValue =
00346             static_cast<boost::uint16_t>(daqPartitionFinalOR);
00347 
00348         finalOrValue = finalOrValue | (daqPartitionFinalORValue << iDaq);
00349 
00350     }
00351 
00352 
00353     // fill everything we know in the L1GtFdlWord
00354 
00355     typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
00356     for (CItBoardMaps
00357             itBoard = boardMaps.begin();
00358             itBoard != boardMaps.end(); ++itBoard) {
00359 
00360 
00361         if ((itBoard->gtBoardType() == FDL)) {
00362 
00363             m_gtFdlWord->setBoardId( itBoard->gtBoardId() );
00364 
00365             // BxInEvent
00366             m_gtFdlWord->setBxInEvent(iBxInEvent);
00367 
00368             // bunch crossing
00369 
00370             // fill in emulator the same bunch crossing (12 bits - hardwired number of bits...)
00371             // and the same local bunch crossing for all boards
00372             int bxCross = iEvent.bunchCrossing();
00373             boost::uint16_t bxCrossHw = 0;
00374             if ((bxCross & 0xFFF) == bxCross) {
00375                 bxCrossHw = static_cast<boost::uint16_t> (bxCross);
00376             }
00377             else {
00378                 bxCrossHw = 0; // Bx number too large, set to 0!
00379                 if (m_verbosity) {
00380                     LogDebug("L1GlobalTrigger")
00381                         << "\nBunch cross number [hex] = "
00382                         << std::hex << bxCross
00383                         << "\n  larger than 12 bits. Set to 0! \n"
00384                         << std::dec << std::endl;
00385                 }
00386             }
00387 
00388             m_gtFdlWord->setBxNr(bxCrossHw);
00389 
00390             // set event number since last L1 reset generated in FDL
00391             m_gtFdlWord->setEventNr(
00392                 static_cast<boost::uint32_t>(iEvent.id().event()) );
00393 
00394             // technical trigger decision word
00395             m_gtFdlWord->setGtTechnicalTriggerWord(techDecisionWord);
00396 
00397             // algorithm trigger decision word
00398             m_gtFdlWord->setGtDecisionWord(algoDecisionWord);
00399 
00400             // index of prescale factor set - technical triggers and algo
00401             m_gtFdlWord->setGtPrescaleFactorIndexTech(static_cast<boost::uint16_t>(pfTechSetIndex));
00402             m_gtFdlWord->setGtPrescaleFactorIndexAlgo(static_cast<boost::uint16_t>(pfAlgoSetIndex));
00403 
00404             // NoAlgo bit FIXME
00405 
00406             // finalOR
00407             m_gtFdlWord->setFinalOR(finalOrValue);
00408 
00409             // orbit number
00410             m_gtFdlWord->setOrbitNr(static_cast<boost::uint32_t>(iEvent.orbitNumber()) );
00411 
00412             // luminosity segment number
00413             m_gtFdlWord->setLumiSegmentNr(static_cast<boost::uint16_t>(iEvent.luminosityBlock()));
00414 
00415             // local bunch crossing - set identical with absolute BxNr
00416             m_gtFdlWord->setLocalBxNr(bxCrossHw);
00417 
00418 
00419         }
00420 
00421     }
00422 
00423 }
00424 
00425 // fill the FDL block in the L1 GT DAQ record for iBxInEvent
00426 void L1GlobalTriggerFDL::fillDaqFdlBlock(const int iBxInEvent,
00427         const boost::uint16_t& activeBoardsGtDaq, const int recordLength0,
00428         const int recordLength1, const unsigned int altNrBxBoardDaq,
00429         const std::vector<L1GtBoard>& boardMaps,
00430         std::auto_ptr<L1GlobalTriggerReadoutRecord>& gtDaqReadoutRecord)
00431 {
00432 
00433     typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
00434     for (CItBoardMaps
00435             itBoard = boardMaps.begin();
00436             itBoard != boardMaps.end(); ++itBoard) {
00437 
00438         int iPosition = itBoard->gtPositionDaqRecord();
00439         if (iPosition > 0) {
00440 
00441             int iActiveBit = itBoard->gtBitDaqActiveBoards();
00442             bool activeBoard = false;
00443             bool writeBoard = false;
00444 
00445             int recLength = -1;
00446 
00447             if (iActiveBit >= 0) {
00448                 activeBoard = activeBoardsGtDaq & ( 1 << iActiveBit );
00449 
00450                 int altNrBxBoard = (altNrBxBoardDaq & ( 1 << iActiveBit )) >> iActiveBit;
00451 
00452                 if (altNrBxBoard == 1) {
00453                     recLength = recordLength1;
00454                 } else {
00455                     recLength = recordLength0;
00456                 }
00457 
00458                 int lowBxInEvent = (recLength + 1)/2 - recLength;
00459                 int uppBxInEvent = (recLength + 1)/2 - 1;
00460 
00461                 if ((iBxInEvent >= lowBxInEvent) && (iBxInEvent <= uppBxInEvent)) {
00462                     writeBoard = true;
00463                 }
00464 
00465             }
00466 
00467             if (activeBoard && writeBoard && (itBoard->gtBoardType() == FDL)) {
00468 
00469                 gtDaqReadoutRecord->setGtFdlWord(*m_gtFdlWord);
00470 
00471 
00472             }
00473 
00474         }
00475 
00476     }
00477 
00478 
00479 }
00480 
00481 // fill the FDL block in the L1 GT EVM record for iBxInEvent
00482 void L1GlobalTriggerFDL::fillEvmFdlBlock(const int iBxInEvent,
00483         const boost::uint16_t& activeBoardsGtEvm, const int recordLength0,
00484         const int recordLength1, const unsigned int altNrBxBoardEvm,
00485         const std::vector<L1GtBoard>& boardMaps,
00486         std::auto_ptr<L1GlobalTriggerEvmReadoutRecord>& gtEvmReadoutRecord)
00487 {
00488 
00489     typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
00490     for (CItBoardMaps
00491             itBoard = boardMaps.begin();
00492             itBoard != boardMaps.end(); ++itBoard) {
00493 
00494         int iPosition = itBoard->gtPositionEvmRecord();
00495         if (iPosition > 0) {
00496 
00497             int iActiveBit = itBoard->gtBitEvmActiveBoards();
00498             bool activeBoard = false;
00499 
00500             if (iActiveBit >= 0) {
00501                 activeBoard = activeBoardsGtEvm & (1 << iActiveBit);
00502             }
00503 
00504             if (activeBoard && (itBoard->gtBoardType() == FDL)) {
00505 
00506                 gtEvmReadoutRecord->setGtFdlWord(*m_gtFdlWord);
00507 
00508 
00509             }
00510 
00511         }
00512 
00513     }
00514 
00515 }
00516 
00517 
00518 // clear FDL
00519 void L1GlobalTriggerFDL::reset()
00520 {
00521 
00522     m_gtFdlWord->reset();
00523 
00524     // do NOT reset the prescale counters
00525 
00526 }