CMS 3D CMS Logo

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