CMS 3D CMS Logo

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