CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/EventFilter/L1GlobalTriggerRawToDigi/src/L1GlobaTriggerEvmRawToDigi.cc

Go to the documentation of this file.
00001 
00017 // this class header
00018 #include "EventFilter/L1GlobalTriggerRawToDigi/interface/L1GlobalTriggerEvmRawToDigi.h"
00019 
00020 // system include files
00021 #include <boost/cstdint.hpp>
00022 #include <iostream>
00023 #include <iomanip>
00024 #include <algorithm>
00025 
00026 // user include files
00027 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
00028 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerEvmReadoutRecord.h"
00029 
00030 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00031 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00032 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00033 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00034 
00035 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeWord.h"
00036 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeExtWord.h"
00037 #include "DataFormats/L1GlobalTrigger/interface/L1TcsWord.h"
00038 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
00039 
00040 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00041 #include "FWCore/Utilities/interface/InputTag.h"
00042 
00043 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00044 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00045 
00046 #include "FWCore/Framework/interface/EventSetup.h"
00047 #include "FWCore/Framework/interface/ESHandle.h"
00048 
00049 #include "CondFormats/L1TObjects/interface/L1GtFwd.h"
00050 #include "CondFormats/L1TObjects/interface/L1GtBoard.h"
00051 
00052 #include "CondFormats/L1TObjects/interface/L1GtBoardMaps.h"
00053 #include "CondFormats/DataRecord/interface/L1GtBoardMapsRcd.h"
00054 
00055 #include "CondFormats/L1TObjects/interface/L1GtParameters.h"
00056 #include "CondFormats/DataRecord/interface/L1GtParametersRcd.h"
00057 
00058 // constructor(s)
00059 L1GlobalTriggerEvmRawToDigi::L1GlobalTriggerEvmRawToDigi(const edm::ParameterSet& pSet) :
00060 
00061     // input tag for EVM GT record
00062             m_evmGtInputTag(pSet.getParameter<edm::InputTag> ("EvmGtInputTag")),
00063 
00064             // FED Id for GT EVM record
00065             // default value defined in DataFormats/FEDRawData/src/FEDNumbering.cc
00066             // default value: assume the EVM record is the first GT record
00067             m_evmGtFedId(pSet.getUntrackedParameter<int> (
00068                     "EvmGtFedId", FEDNumbering::MINTriggerGTPFEDID)),
00069 
00070             // mask for active boards
00071             m_activeBoardsMaskGt(pSet.getParameter<unsigned int> ("ActiveBoardsMask")),
00072 
00073             // number of bunch crossing to be unpacked
00074             m_unpackBxInEvent(pSet.getParameter<int> ("UnpackBxInEvent")),
00075 
00076             m_lowSkipBxInEvent(0), m_uppSkipBxInEvent(0),
00077 
00078             m_recordLength0(0), m_recordLength1(0),
00079 
00080             m_totalBxInEvent(0),
00081 
00082             // length of BST record (in bytes)
00083             m_bstLengthBytes(pSet.getParameter<int> ("BstLengthBytes")),
00084 
00085             m_verbosity(pSet.getUntrackedParameter<int> ("Verbosity", 0)),
00086 
00087             m_isDebugEnabled(edm::isDebugEnabled())
00088 
00089 {
00090 
00091     produces<L1GlobalTriggerEvmReadoutRecord> ();
00092 
00093     if (m_verbosity && m_isDebugEnabled) {
00094 
00095         LogDebug("L1GlobalTriggerEvmRawToDigi")
00096                 << "\nInput tag for EVM GT record:             " << m_evmGtInputTag
00097                 << "\nFED Id for EVM GT record:                " << m_evmGtFedId
00098                 << "\nMask for active boards (hex format):     " << std::hex
00099                 << std::setw(sizeof(m_activeBoardsMaskGt) * 2) << std::setfill('0')
00100                 << m_activeBoardsMaskGt
00101                 << std::dec << std::setfill(' ')
00102                 << "\nNumber of bunch crossing to be unpacked: " << m_unpackBxInEvent
00103                 << "\nLength of BST message [bytes]:           " << m_bstLengthBytes << "\n"
00104                 << std::endl;
00105     }
00106 
00107     if ( ( m_unpackBxInEvent > 0 ) && ( ( m_unpackBxInEvent % 2 ) == 0 )) {
00108         m_unpackBxInEvent = m_unpackBxInEvent - 1;
00109 
00110         if (m_verbosity) {
00111             edm::LogInfo("L1GlobalTriggerEvmRawToDigi")
00112                     << "\nWARNING: Number of bunch crossing to be unpacked rounded to: "
00113                     << m_unpackBxInEvent << "\n         The number must be an odd number!\n"
00114                     << std::endl;
00115         }
00116     }
00117 
00118     // create GTFE, TCS, FDL cards once per analyzer
00119     // content will be reset whenever needed
00120 
00121     m_gtfeWord = new L1GtfeExtWord();
00122     m_tcsWord = new L1TcsWord();
00123     m_gtFdlWord = new L1GtFdlWord();
00124 
00125 }
00126 
00127 // destructor
00128 L1GlobalTriggerEvmRawToDigi::~L1GlobalTriggerEvmRawToDigi() {
00129 
00130     delete m_gtfeWord;
00131     delete m_tcsWord;
00132     delete m_gtFdlWord;
00133 
00134 }
00135 
00136 // member functions
00137 
00138 void L1GlobalTriggerEvmRawToDigi::beginJob() {
00139 
00140     // empty now
00141 
00142 }
00143 
00144 // method called to produce the data
00145 void L1GlobalTriggerEvmRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& evSetup) {
00146 
00147     // get records from EventSetup
00148 
00149     //  board maps
00150     edm::ESHandle<L1GtBoardMaps> l1GtBM;
00151     evSetup.get<L1GtBoardMapsRcd> ().get(l1GtBM);
00152 
00153     const std::vector<L1GtBoard> boardMaps = l1GtBM->gtBoardMaps();
00154     int boardMapsSize = boardMaps.size();
00155 
00156     typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
00157 
00158     // create an ordered vector for the GT EVM record
00159     // header (pos 0 in record) and trailer (last position in record)
00160     // not included, as they are not in board list
00161     std::vector<L1GtBoard> gtRecordMap;
00162     gtRecordMap.reserve(boardMapsSize);
00163 
00164     for (int iPos = 0; iPos < boardMapsSize; ++iPos) {
00165         for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
00166 
00167             if (itBoard->gtPositionEvmRecord() == iPos) {
00168                 gtRecordMap.push_back(*itBoard);
00169                 break;
00170             }
00171 
00172         }
00173     }
00174 
00175     // raw collection
00176 
00177     edm::Handle<FEDRawDataCollection> fedHandle;
00178     iEvent.getByLabel(m_evmGtInputTag, fedHandle);
00179 
00180     if (!fedHandle.isValid()) {
00181         if (m_verbosity) {
00182             edm::LogWarning("L1GlobalTriggerEvmRawToDigi")
00183                     << "\nWarning: FEDRawDataCollection with input tag " << m_evmGtInputTag
00184                     << "\nrequested in configuration, but not found in the event."
00185                     << "\nQuit unpacking this event" << std::endl;
00186         }
00187 
00188         produceEmptyProducts(iEvent);
00189 
00190         return;
00191     }
00192 
00193     // retrieve data for Global Trigger EVM FED
00194     const FEDRawData& raw = ( fedHandle.product() )->FEDData(m_evmGtFedId);
00195 
00196     int gtSize = raw.size();
00197 
00198     // get a const pointer to the beginning of the data buffer
00199     const unsigned char* ptrGt = raw.data();
00200 
00201     // get a const pointer to the end of the data buffer
00202     const unsigned char* endPtrGt = ptrGt + gtSize;
00203 
00204     //
00205     if (m_verbosity && m_isDebugEnabled) {
00206 
00207         LogTrace("L1GlobalTriggerEvmRawToDigi") << "\n Size of raw data: "
00208                 << gtSize << "\n" << std::endl;
00209 
00210         std::ostringstream myCoutStream;
00211         dumpFedRawData(ptrGt, gtSize, myCoutStream);
00212 
00213         LogTrace("L1GlobalTriggerEvmRawToDigi") << "\n Dump FEDRawData\n"
00214                 << myCoutStream.str() << "\n" << std::endl;
00215 
00216     }
00217 
00218     // unpack header
00219     int headerSize = 8;
00220 
00221     if ((ptrGt + headerSize) > endPtrGt) {
00222         edm::LogError("L1GlobalTriggerEvmRawToDigi")
00223                 << "\nError: Pointer after header greater than end pointer."
00224                 << "\n Put empty products in the event!"
00225                 << "\n Quit unpacking this event." << std::endl;
00226 
00227         produceEmptyProducts(iEvent);
00228 
00229         return;
00230     }
00231 
00232     FEDHeader cmsHeader(ptrGt);
00233     FEDTrailer cmsTrailer(ptrGt + gtSize - headerSize);
00234 
00235     unpackHeader(ptrGt, cmsHeader);
00236     ptrGt += headerSize; // advance with header size
00237 
00238     // unpack first GTFE to find the length of the record and the active boards
00239     // here GTFE assumed immediately after the header
00240 
00241     bool gtfeUnpacked = false;
00242 
00243     // get the length of the BST message from parameter set or from event setup
00244 
00245     int bstLengthBytes = 0;
00246 
00247     if (m_bstLengthBytes < 0) {
00248         // length from event setup // TODO cache it, if too slow
00249 
00250         edm::ESHandle<L1GtParameters> l1GtPar;
00251         evSetup.get<L1GtParametersRcd> ().get(l1GtPar);
00252         const L1GtParameters* m_l1GtPar = l1GtPar.product();
00253 
00254         bstLengthBytes = static_cast<int> (m_l1GtPar->gtBstLengthBytes());
00255 
00256     } else {
00257         // length from parameter set
00258         bstLengthBytes = m_bstLengthBytes;
00259     }
00260 
00261     if (m_verbosity) {
00262         LogTrace("L1GlobalTriggerEvmRawToDigi") << "\n Length of BST message (in bytes): "
00263                 << bstLengthBytes << "\n" << std::endl;
00264     }
00265 
00266     for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
00267 
00268         if (itBoard->gtBoardType() == GTFE) {
00269 
00270             // unpack GTFE
00271             if (itBoard->gtPositionEvmRecord() == 1) {
00272 
00273                 // resize to the right size before unapacking
00274                 m_gtfeWord->resize(bstLengthBytes);
00275 
00276                 m_gtfeWord->unpack(ptrGt);
00277                 ptrGt += m_gtfeWord->getSize(); // advance with GTFE block size
00278                 gtfeUnpacked = true;
00279 
00280                 if (m_verbosity && m_isDebugEnabled) {
00281 
00282                     std::ostringstream myCoutStream;
00283                     m_gtfeWord->print(myCoutStream);
00284                     LogTrace("L1GlobalTriggerEvmRawToDigi") << myCoutStream.str() << "\n"
00285                             << std::endl;
00286                 }
00287 
00288                 // break the loop - GTFE was found
00289                 break;
00290 
00291             } else {
00292 
00293                 if (m_verbosity) {
00294                     edm::LogWarning("L1GlobalTriggerEvmRawToDigi")
00295                             << "\nWarning: GTFE block found in raw data does not follow header."
00296                             << "\nAssumed start position of the block is wrong!"
00297                             << "\nQuit unpacking this event" << std::endl;
00298                 }
00299 
00300                 produceEmptyProducts(iEvent);
00301 
00302                 return;
00303 
00304             }
00305 
00306         }
00307     }
00308 
00309     // quit if no GTFE found
00310     if (!gtfeUnpacked) {
00311 
00312         if (m_verbosity) {
00313             edm::LogWarning("L1GlobalTriggerEvmRawToDigi")
00314                     << "\nWarning: no GTFE block found in raw data."
00315                     << "\nCan not find the record length (BxInEvent) and the active boards!"
00316                     << "\nQuit unpacking this event" << std::endl;
00317         }
00318 
00319         produceEmptyProducts(iEvent);
00320 
00321         return;
00322     }
00323 
00324     // life normal here, GTFE found
00325 
00326     // get list of active blocks
00327     // blocks not active are not written to the record
00328     boost::uint16_t activeBoardsGtInitial = m_gtfeWord->activeBoards();
00329     boost::uint16_t altNrBxBoardInitial = m_gtfeWord->altNrBxBoard();
00330 
00331     // mask some boards, if needed
00332     boost::uint16_t activeBoardsGt = activeBoardsGtInitial & m_activeBoardsMaskGt;
00333     m_gtfeWord->setActiveBoards(activeBoardsGt);
00334 
00335     if (m_verbosity) {
00336         LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nActive boards before masking(hex format): "
00337                 << std::hex << std::setw(sizeof ( activeBoardsGtInitial ) * 2) << std::setfill('0')
00338                 << activeBoardsGtInitial << std::dec << std::setfill(' ')
00339                 << "\nActive boards after masking(hex format):  " << std::hex << std::setw(
00340                 sizeof ( activeBoardsGt ) * 2) << std::setfill('0') << activeBoardsGt << std::dec
00341                 << std::setfill(' ') << " \n" << std::endl;
00342     }
00343 
00344     // loop over other blocks in the raw record, count them if they are active
00345 
00346     int numberGtfeBoards = 0;
00347     int numberFdlBoards = 0;
00348     int numberPsbBoards = 0;
00349     int numberGmtBoards = 0;
00350     int numberTcsBoards = 0;
00351     int numberTimBoards = 0;
00352 
00353     for (CItBoardMaps itBoard = boardMaps.begin(); itBoard != boardMaps.end(); ++itBoard) {
00354 
00355         int iActiveBit = itBoard->gtBitEvmActiveBoards();
00356         bool activeBoardToUnpack = false;
00357 
00358         if (iActiveBit >= 0) {
00359             activeBoardToUnpack = activeBoardsGt & ( 1 << iActiveBit );
00360         } else {
00361             // board not in the ActiveBoards for the record
00362             continue;
00363         }
00364 
00365         if (activeBoardToUnpack) {
00366 
00367             switch (itBoard->gtBoardType()) {
00368                 case GTFE: {
00369                     numberGtfeBoards++;
00370                 }
00371 
00372                     break;
00373                 case FDL: {
00374                     numberFdlBoards++;
00375                 }
00376 
00377                     break;
00378                 case PSB: {
00379                     numberPsbBoards++;
00380                 }
00381 
00382                     break;
00383                 case GMT: {
00384                     numberGmtBoards++;
00385                 }
00386 
00387                     break;
00388                 case TCS: {
00389                     numberTcsBoards++;
00390                 }
00391 
00392                     break;
00393                 case TIM: {
00394                     numberTimBoards++;
00395                 }
00396 
00397                     break;
00398                 default: {
00399                     // do nothing, all blocks are given in GtBoardType enum
00400                     if (m_verbosity) {
00401                         LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nBoard of type "
00402                                 << itBoard->gtBoardType() << " not expected  in record.\n"
00403                                 << std::endl;
00404                     }
00405 
00406                 }
00407 
00408                     break;
00409             }
00410         }
00411 
00412     }
00413 
00414     // produce the L1GlobalTriggerEvmReadoutRecord now, after we found how many
00415     // BxInEvent the record has and how many boards are active
00416     //LogDebug("L1GlobalTriggerEvmRawToDigi")
00417     //<< "\nL1GlobalTriggerEvmRawToDigi: producing L1GlobalTriggerEvmReadoutRecord\n"
00418     //<< std::endl;
00419 
00420     // get number of Bx in the event from GTFE block corresponding to alternative 0 and 1 in
00421     m_recordLength0 = m_gtfeWord->recordLength();
00422     m_recordLength1 = m_gtfeWord->recordLength1();
00423 
00424     int maxBxInEvent = std::max(m_recordLength0, m_recordLength1);
00425 
00426     std::auto_ptr<L1GlobalTriggerEvmReadoutRecord> gtReadoutRecord(
00427             new L1GlobalTriggerEvmReadoutRecord(maxBxInEvent, numberFdlBoards));
00428 
00429     // ... then unpack modules other than GTFE, if requested
00430 
00431     for (CItBoardMaps itBoard = gtRecordMap.begin(); itBoard != gtRecordMap.end(); ++itBoard) {
00432 
00433         int iActiveBit = itBoard->gtBitEvmActiveBoards();
00434 
00435         bool activeBoardToUnpack = false;
00436         bool activeBoardInitial = false;
00437 
00438         int altNrBxBoardVal = -1;
00439 
00440         if (iActiveBit >= 0) {
00441             activeBoardInitial = activeBoardsGtInitial & ( 1 << iActiveBit );
00442             activeBoardToUnpack = activeBoardsGt & ( 1 << iActiveBit );
00443 
00444             altNrBxBoardVal = (altNrBxBoardInitial & ( 1 << iActiveBit )) >> iActiveBit;
00445 
00446             if (altNrBxBoardVal == 1) {
00447                 m_totalBxInEvent = m_recordLength1;
00448             } else if (altNrBxBoardVal == 0) {
00449                 m_totalBxInEvent = m_recordLength0;
00450             } else {
00451                 if (m_verbosity) {
00452                     edm::LogWarning("L1GlobalTriggerEvmRawToDigi")
00453                             << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal
00454                             << " for board " << std::hex << ( itBoard->gtBoardId() ) << std::dec
00455                             << "\n  iActiveBit =            " << iActiveBit
00456                             << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial <<  std::dec
00457                             << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt <<  std::dec
00458                             << "\n  activeBoardInitial =    " << activeBoardInitial
00459                             << "\n  activeBoardToUnpack =   " << activeBoardToUnpack
00460                             << "\n Set altNrBxBoardVal tentatively to "
00461                             << m_recordLength0 << "\n Job may crash or produce wrong results!\n\n"
00462                             << std::endl;
00463                 }
00464 
00465                 m_totalBxInEvent = m_recordLength0;
00466             }
00467 
00468             // number of BX required to be unpacked
00469 
00470             if (m_unpackBxInEvent > m_totalBxInEvent) {
00471                 if (m_verbosity) {
00472                     LogDebug("L1GlobalTriggerEvmRawToDigi")
00473                             << "\nWARNING: Number of available bunch crosses for board"
00474                             << ( itBoard->gtBoardId() ) << " in the record ( " << m_totalBxInEvent
00475                             << " ) \n is smaller than the number of bunch crosses requested to be unpacked ("
00476                             << m_unpackBxInEvent << " )!!! \n         Unpacking only "
00477                             << m_totalBxInEvent << " bunch crosses.\n" << std::endl;
00478                 }
00479 
00480                 m_lowSkipBxInEvent = 0;
00481                 m_uppSkipBxInEvent = m_totalBxInEvent;
00482 
00483             } else if (m_unpackBxInEvent < 0) {
00484 
00485                 m_lowSkipBxInEvent = 0;
00486                 m_uppSkipBxInEvent = m_totalBxInEvent;
00487 
00488                 if (m_verbosity) {
00489                     LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nUnpacking all " << m_totalBxInEvent
00490                             << " bunch crosses available." << "\n" << std::endl;
00491                 }
00492 
00493             } else if (m_unpackBxInEvent == 0) {
00494 
00495                 m_lowSkipBxInEvent = m_totalBxInEvent;
00496                 m_uppSkipBxInEvent = m_totalBxInEvent;
00497 
00498                 if (m_verbosity) {
00499                     LogDebug("L1GlobalTriggerEvmRawToDigi")
00500                             << "\nNo bxInEvent required to be unpacked from " << m_totalBxInEvent
00501                             << " bunch crosses available." << "\n" << std::endl;
00502                 }
00503 
00504                 // change RecordLength
00505                 // cast int to boost::uint16_t (there are normally 3 or 5 BxInEvent)
00506                 m_gtfeWord->setRecordLength(static_cast<boost::uint16_t> (m_unpackBxInEvent));
00507                 m_gtfeWord->setRecordLength1(static_cast<boost::uint16_t> (m_unpackBxInEvent));
00508 
00509             } else {
00510 
00511                 m_lowSkipBxInEvent = ( m_totalBxInEvent - m_unpackBxInEvent ) / 2;
00512                 m_uppSkipBxInEvent = m_totalBxInEvent - m_lowSkipBxInEvent;
00513 
00514                 if (m_verbosity) {
00515                     LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nUnpacking " << m_unpackBxInEvent
00516                             << " bunch crosses from " << m_totalBxInEvent
00517                             << " bunch crosses available." << "\n" << std::endl;
00518                 }
00519 
00520                 // change RecordLength
00521                 // cast int to boost::uint16_t (there are normally 3 or 5 BxInEvent)
00522                 m_gtfeWord->setRecordLength(static_cast<boost::uint16_t> (m_unpackBxInEvent));
00523                 m_gtfeWord->setRecordLength1(static_cast<boost::uint16_t> (m_unpackBxInEvent));
00524 
00525             }
00526 
00527         } else {
00528             // board not in the ActiveBoards for the record
00529             continue;
00530         }
00531 
00532         if (!activeBoardInitial) {
00533             if (m_verbosity) {
00534                 LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nBoard of type "
00535                         << itBoard->gtBoardName() << " with index " << itBoard->gtBoardIndex()
00536                         << " not active initially in raw data.\n" << std::endl;
00537             }
00538             continue;
00539         }
00540 
00541         // active board initially, could unpack it
00542         switch (itBoard->gtBoardType()) {
00543 
00544             case TCS: {
00545 
00546                 // if pointer after TCS payload is greater than pointer at
00547                 // the end of GT payload, produce empty products and quit unpacking
00548                 if ((ptrGt + m_tcsWord->getSize()) > endPtrGt) {
00549                     edm::LogError("L1GlobalTriggerEvmRawToDigi")
00550                             << "\nError: Pointer after TCS "
00551                             << " greater than end pointer."
00552                             << "\n Put empty products in the event!"
00553                             << "\n Quit unpacking this event." << std::endl;
00554 
00555                     produceEmptyProducts(iEvent);
00556 
00557                     return;
00558                 }
00559 
00560                 // unpack only if requested, otherwise skip it
00561                 if (activeBoardToUnpack) {
00562 
00563                     m_tcsWord->unpack(ptrGt);
00564 
00565                     // add 1 to the GT luminosity number to use the same convention as
00566                     // offline, where LS number starts with 1;
00567                     // in GT hardware, LS starts with 0
00568                     boost::uint16_t lsNr = m_tcsWord->luminositySegmentNr() + 1;
00569                     m_tcsWord->setLuminositySegmentNr(lsNr);
00570 
00571                     // add TCS block to GT EVM readout record
00572                     gtReadoutRecord->setTcsWord(*m_tcsWord);
00573 
00574                     if (m_verbosity && m_isDebugEnabled) {
00575 
00576                         std::ostringstream myCoutStream;
00577                         m_tcsWord->print(myCoutStream);
00578                         LogTrace("L1GlobalTriggerEvmRawToDigi") << myCoutStream.str() << "\n"
00579                                 << std::endl;
00580                     }
00581 
00582                     // ... and reset it
00583                     m_tcsWord->reset();
00584                 }
00585 
00586                 ptrGt += m_tcsWord->getSize(); // advance with TCS block size
00587 
00588             }
00589                 break;
00590             case FDL: {
00591                 for (int iFdl = 0; iFdl < m_totalBxInEvent; ++iFdl) {
00592 
00593                     // if pointer after FDL payload is greater than pointer at
00594                     // the end of GT payload, produce empty products and quit unpacking
00595                     if ((ptrGt + m_gtFdlWord->getSize()) > endPtrGt) {
00596                         edm::LogError("L1GlobalTriggerEvmRawToDigi")
00597                                 << "\nError: Pointer after FDL " << iFdl
00598                                 << " greater than end pointer."
00599                                 << "\n Put empty products in the event!"
00600                                 << "\n Quit unpacking this event." << std::endl;
00601 
00602                         produceEmptyProducts(iEvent);
00603 
00604                         return;
00605                     }
00606 
00607                     // unpack only if requested, otherwise skip it
00608                     if (activeBoardToUnpack) {
00609 
00610                         // unpack only bxInEvent requested, otherwise skip it
00611                         if ( ( iFdl >= m_lowSkipBxInEvent ) && ( iFdl < m_uppSkipBxInEvent )) {
00612 
00613                             m_gtFdlWord->unpack(ptrGt);
00614 
00615                             // add 1 to the GT luminosity number to use the same convention as
00616                             // offline, where LS number starts with 1;
00617                             // in GT hardware, LS starts with 0
00618                             boost::uint16_t lsNr = m_gtFdlWord->lumiSegmentNr() + 1;
00619                             m_gtFdlWord->setLumiSegmentNr(lsNr);
00620 
00621                             // add FDL block to GT readout record
00622                             gtReadoutRecord->setGtFdlWord(*m_gtFdlWord);
00623 
00624                             if (m_verbosity && m_isDebugEnabled) {
00625 
00626                                 std::ostringstream myCoutStream;
00627                                 m_gtFdlWord->print(myCoutStream);
00628                                 LogTrace("L1GlobalTriggerEvmRawToDigi") << myCoutStream.str()
00629                                         << "\n" << std::endl;
00630                             }
00631 
00632                             // ... and reset it
00633                             m_gtFdlWord->reset();
00634                         }
00635 
00636                     }
00637 
00638                     ptrGt += m_gtFdlWord->getSize(); // advance with FDL block size
00639 
00640                 }
00641             }
00642 
00643                 break;
00644             default: {
00645                 // do nothing, all blocks are given in GtBoardType enum
00646                 if (m_verbosity) {
00647                     LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nBoard of type "
00648                             << itBoard->gtBoardType() << " not expected  in record.\n" << std::endl;
00649                 }
00650             }
00651                 break;
00652 
00653         }
00654 
00655     }
00656 
00657     // add GTFE block to GT readout record, after updating active boards and record length
00658 
00659     gtReadoutRecord->setGtfeWord(*m_gtfeWord);
00660 
00661     // ... and reset it
00662     m_gtfeWord->reset();
00663 
00664     // unpack trailer
00665 
00666     int trailerSize = 8;
00667 
00668     // if pointer after trailer is greater than pointer at
00669     // the end of GT payload, produce empty products and quit unpacking
00670     if ((ptrGt + trailerSize) > endPtrGt) {
00671         edm::LogError("L1GlobalTriggerEvmRawToDigi")
00672                 << "\nError: Pointer after trailer "
00673                 << " greater than end pointer."
00674                 << "\n Put empty products in the event!"
00675                 << "\n Quit unpacking this event." << std::endl;
00676 
00677         produceEmptyProducts(iEvent);
00678 
00679         return;
00680     }
00681 
00682     unpackTrailer(ptrGt, cmsTrailer);
00683 
00684     if (m_verbosity && m_isDebugEnabled) {
00685         std::ostringstream myCoutStream;
00686         gtReadoutRecord->print(myCoutStream);
00687         LogTrace("L1GlobalTriggerEvmRawToDigi")
00688                 << "\n The following L1 GT EVM readout record was unpacked.\n"
00689                 << myCoutStream.str() << "\n" << std::endl;
00690     }
00691 
00692     // put records into event
00693     iEvent.put(gtReadoutRecord);
00694 
00695 }
00696 
00697 // unpack header
00698 void L1GlobalTriggerEvmRawToDigi::unpackHeader(const unsigned char* gtPtr, FEDHeader& cmsHeader) {
00699 
00700     // TODO  if needed in another format
00701 
00702     // print the header info
00703     if (edm::isDebugEnabled()) {
00704 
00705         const boost::uint64_t* payload =
00706                 reinterpret_cast<boost::uint64_t*> (const_cast<unsigned char*> (gtPtr));
00707 
00708         std::ostringstream myCoutStream;
00709 
00710         // one word only
00711         int iWord = 0;
00712 
00713         myCoutStream << std::setw(4) << iWord << "  " << std::hex << std::setfill('0')
00714                 << std::setw(16) << payload[iWord] << std::dec << std::setfill(' ') << "\n"
00715                 << std::endl;
00716 
00717         myCoutStream << "  Event_type:  " << std::hex << " hex: " << "     " << std::setw(1)
00718                 << std::setfill('0') << cmsHeader.triggerType() << std::setfill(' ') << std::dec
00719                 << " dec: " << cmsHeader.triggerType() << std::endl;
00720 
00721         myCoutStream << "  LVL1_Id:     " << std::hex << " hex: " << "" << std::setw(6)
00722                 << std::setfill('0') << cmsHeader.lvl1ID() << std::setfill(' ') << std::dec
00723                 << " dec: " << cmsHeader.lvl1ID() << std::endl;
00724 
00725         myCoutStream << "  BX_Id:       " << std::hex << " hex: " << "   " << std::setw(3)
00726                 << std::setfill('0') << cmsHeader.bxID() << std::setfill(' ') << std::dec
00727                 << " dec: " << cmsHeader.bxID() << std::endl;
00728 
00729         myCoutStream << "  Source_Id:   " << std::hex << " hex: " << "   " << std::setw(3)
00730                 << std::setfill('0') << cmsHeader.sourceID() << std::setfill(' ') << std::dec
00731                 << " dec: " << cmsHeader.sourceID() << std::endl;
00732 
00733         myCoutStream << "  FOV:         " << std::hex << " hex: " << "     " << std::setw(1)
00734                 << std::setfill('0') << cmsHeader.version() << std::setfill(' ') << std::dec
00735                 << " dec: " << cmsHeader.version() << std::endl;
00736 
00737         myCoutStream << "  H:           " << std::hex << " hex: " << "     " << std::setw(1)
00738                 << std::setfill('0') << cmsHeader.moreHeaders() << std::setfill(' ') << std::dec
00739                 << " dec: " << cmsHeader.moreHeaders() << std::endl;
00740 
00741         LogDebug("L1GlobalTriggerEvmRawToDigi") << "\n CMS Header \n" << myCoutStream.str() << "\n"
00742                 << std::endl;
00743 
00744     }
00745 
00746 }
00747 
00748 // unpack trailer word
00749 // trPtr pointer to the beginning of trailer obtained from gtPtr
00750 void L1GlobalTriggerEvmRawToDigi::unpackTrailer(const unsigned char* trlPtr, FEDTrailer& cmsTrailer) {
00751 
00752     // TODO  if needed in another format
00753 
00754     // print the trailer info
00755     if (m_verbosity && m_isDebugEnabled) {
00756 
00757         const boost::uint64_t* payload =
00758                 reinterpret_cast<boost::uint64_t*> (const_cast<unsigned char*> (trlPtr));
00759 
00760         std::ostringstream myCoutStream;
00761 
00762         // one word only
00763         int iWord = 0;
00764 
00765         myCoutStream << std::setw(4) << iWord << "  " << std::hex << std::setfill('0')
00766                 << std::setw(16) << payload[iWord] << std::dec << std::setfill(' ') << "\n"
00767                 << std::endl;
00768 
00769         myCoutStream << "  Event_length:  " << std::hex << " hex: " << "" << std::setw(6)
00770                 << std::setfill('0') << cmsTrailer.lenght() << std::setfill(' ') << std::dec
00771                 << " dec: " << cmsTrailer.lenght() << std::endl;
00772 
00773         myCoutStream << "  CRC:           " << std::hex << " hex: " << "  " << std::setw(4)
00774                 << std::setfill('0') << cmsTrailer.crc() << std::setfill(' ') << std::dec
00775                 << " dec: " << cmsTrailer.crc() << std::endl;
00776 
00777         myCoutStream << "  Event_status:  " << std::hex << " hex: " << "    " << std::setw(2)
00778                 << std::setfill('0') << cmsTrailer.evtStatus() << std::setfill(' ') << std::dec
00779                 << " dec: " << cmsTrailer.evtStatus() << std::endl;
00780 
00781         myCoutStream << "  TTS_bits:      " << std::hex << " hex: " << "     " << std::setw(1)
00782                 << std::setfill('0') << cmsTrailer.ttsBits() << std::setfill(' ') << std::dec
00783                 << " dec: " << cmsTrailer.ttsBits() << std::endl;
00784 
00785         myCoutStream << "  More trailers: " << std::hex << " hex: " << "     " << std::setw(1)
00786                 << std::setfill('0') << cmsTrailer.moreTrailers() << std::setfill(' ') << std::dec
00787                 << " dec: " << cmsTrailer.moreTrailers() << std::endl;
00788 
00789         LogDebug("L1GlobalTriggerEvmRawToDigi") << "\n CMS Trailer \n" << myCoutStream.str()
00790                 << "\n" << std::endl;
00791 
00792     }
00793 
00794 }
00795 
00796 // produce empty products in case of problems
00797 void L1GlobalTriggerEvmRawToDigi::produceEmptyProducts(edm::Event& iEvent) {
00798 
00799     std::auto_ptr<L1GlobalTriggerEvmReadoutRecord> gtReadoutRecord(
00800             new L1GlobalTriggerEvmReadoutRecord());
00801 
00802     // put empty records into event
00803 
00804     iEvent.put(gtReadoutRecord);
00805 }
00806 
00807 // dump FED raw data
00808 void L1GlobalTriggerEvmRawToDigi::dumpFedRawData(
00809         const unsigned char* gtPtr, int gtSize, std::ostream& myCout) {
00810 
00811     LogDebug("L1GlobalTriggerEvmRawToDigi") << "\nDump FED raw data.\n" << std::endl;
00812 
00813     int wLength = L1GlobalTriggerReadoutSetup::WordLength;
00814     int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
00815 
00816     int gtWords = gtSize / uLength;
00817     LogTrace("L1GlobalTriggerEvmRawToDigi") << "\nFED GT words (" << wLength << " bits):"
00818             << gtWords << "\n" << std::endl;
00819 
00820     const boost::uint64_t* payload =
00821             reinterpret_cast<boost::uint64_t*> (const_cast<unsigned char*> (gtPtr));
00822 
00823     for (unsigned int i = 0; i < gtSize / sizeof(boost::uint64_t); i++) {
00824         myCout << std::setw(4) << i << "  " << std::hex << std::setfill('0') << std::setw(16)
00825                 << payload[i] << std::dec << std::setfill(' ') << std::endl;
00826     }
00827 
00828 }
00829 
00830 //
00831 void L1GlobalTriggerEvmRawToDigi::endJob() {
00832 
00833     // empty now
00834 }
00835 
00836 // static class members
00837