CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/EventFilter/L1GlobalTriggerRawToDigi/src/L1GTDigiToRaw.cc

Go to the documentation of this file.
00001 
00018 // this class header
00019 #include "EventFilter/L1GlobalTriggerRawToDigi/interface/L1GTDigiToRaw.h"
00020 
00021 // system include files
00022 #include <vector>
00023 #include <iostream>
00024 #include <iomanip>
00025 
00026 
00027 // user include files
00028 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00029 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00030 
00031 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00032 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00033 #include "FWCore/Utilities/interface/CRC16.h"
00034 
00035 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetup.h"
00036 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
00037 
00038 #include "DataFormats/L1GlobalTrigger/interface/L1GtfeWord.h"
00039 #include "DataFormats/L1GlobalTrigger/interface/L1GtFdlWord.h"
00040 #include "DataFormats/L1GlobalTrigger/interface/L1GtPsbWord.h"
00041 #include "DataFormats/L1GlobalTrigger/interface/L1TcsWord.h"
00042 
00043 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuRegionalCand.h"
00044 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTExtendedCand.h"
00045 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTReadoutCollection.h"
00046 
00047 
00048 
00049 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00050 #include "FWCore/MessageLogger/interface/MessageDrop.h"
00051 
00052 #include "FWCore/Framework/interface/EventSetup.h"
00053 #include "FWCore/Framework/interface/ESHandle.h"
00054 
00055 #include "CondFormats/L1TObjects/interface/L1GtFwd.h"
00056 #include "CondFormats/L1TObjects/interface/L1GtBoard.h"
00057 
00058 #include "CondFormats/L1TObjects/interface/L1GtBoardMaps.h"
00059 #include "CondFormats/DataRecord/interface/L1GtBoardMapsRcd.h"
00060 
00061 // constructor(s)
00062 L1GTDigiToRaw::L1GTDigiToRaw(const edm::ParameterSet& pSet) :
00063 
00064     m_daqGtFedId(pSet.getUntrackedParameter<int> (
00065             "DaqGtFedId", FEDNumbering::MAXTriggerGTPFEDID)),
00066     m_daqGtInputTag(pSet.getParameter<edm::InputTag> ("DaqGtInputTag")),
00067     m_muGmtInputTag(pSet.getParameter<edm::InputTag> ("MuGmtInputTag")),
00068     m_activeBoardsMaskGt(pSet.getParameter<unsigned int> ("ActiveBoardsMask")),
00069     m_totalBxInEvent(0),
00070     m_minBxInEvent(0), m_maxBxInEvent(),
00071     m_verbosity(pSet.getUntrackedParameter<int> ("Verbosity", 0)),
00072     m_isDebugEnabled(edm::isDebugEnabled())
00073 
00074 {
00075 
00076     if (m_verbosity && m_isDebugEnabled) {
00077         LogDebug("L1GTDigiToRaw")
00078                 << "\nFED Id for DAQ GT record: " << m_daqGtFedId << " \n"
00079                 << "\nInput tag for DAQ GT record: " << m_daqGtInputTag << " \n"
00080                 << "\nInput tag for GMT record: " << m_muGmtInputTag << " \n"
00081                 << "\nMask for active boards (hex format): " << std::hex
00082                 << std::setw(sizeof(m_activeBoardsMaskGt) * 2) << std::setfill('0')
00083                 << m_activeBoardsMaskGt
00084                 << std::dec << std::setfill(' ') << " \n"
00085                 << std::endl;
00086     }
00087 
00088     //
00089     produces<FEDRawDataCollection> ();
00090 
00091 }
00092 
00093 // destructor
00094 L1GTDigiToRaw::~L1GTDigiToRaw()
00095 {
00096 
00097     // empty now
00098 
00099 }
00100 
00101 // member functions
00102 
00103 // beginning of job stuff
00104 void L1GTDigiToRaw::beginJob()
00105 {
00106 
00107     // empty now
00108 
00109 }
00110 
00111 
00112 // method called to produce the data
00113 void L1GTDigiToRaw::produce(edm::Event& iEvent, const edm::EventSetup& evSetup)
00114 {
00115 
00116     // define new FEDRawDataCollection
00117     // it contains ALL FEDs in an event
00118     std::auto_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
00119 
00120     FEDRawData& gtRawData = allFedRawData->FEDData(m_daqGtFedId);
00121 
00122     // get records from EventSetup
00123 
00124     //  board maps
00125     edm::ESHandle< L1GtBoardMaps > l1GtBM;
00126     evSetup.get< L1GtBoardMapsRcd >().get( l1GtBM );
00127 
00128     const std::vector<L1GtBoard> boardMaps = l1GtBM->gtBoardMaps();
00129     int boardMapsSize = boardMaps.size();
00130 
00131     typedef std::vector<L1GtBoard>::const_iterator CItBoardMaps;
00132 
00133     // create an ordered vector for the GT DAQ record
00134     // header (pos 0 in record) and trailer (last position in record)
00135     // not included, as they are not in board list
00136     std::vector<L1GtBoard> gtRecordMap;
00137     gtRecordMap.reserve(boardMapsSize);
00138 
00139     for (int iPos = 0; iPos < boardMapsSize; ++iPos) {
00140         for (CItBoardMaps itBoard = boardMaps.begin(); itBoard
00141                 != boardMaps.end(); ++itBoard) {
00142 
00143             if (itBoard->gtPositionDaqRecord() == iPos) {
00144                 gtRecordMap.push_back(*itBoard);
00145                 break;
00146             }
00147 
00148         }
00149     }
00150 
00151 
00152     // get L1GlobalTriggerReadoutRecord
00153     edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
00154     iEvent.getByLabel(m_daqGtInputTag, gtReadoutRecord);
00155 
00156     if (!gtReadoutRecord.isValid()) {
00157         if (m_verbosity) {
00158             edm::LogWarning("L1GTDigiToRaw")
00159                     << "\nWarning: L1GlobalTriggerReadoutRecord with input tag " << m_daqGtInputTag
00160                     << "\nrequested in configuration, but not found in the event."
00161                     << "\nQuit packing this event" << std::endl;
00162         }
00163 
00164         // put the raw data in the event
00165         iEvent.put(allFedRawData);
00166 
00167         return;
00168     }
00169 
00170     if (m_verbosity && m_isDebugEnabled) {
00171         std::ostringstream myCoutStream;
00172         gtReadoutRecord->print(myCoutStream);
00173         LogTrace("L1GTDigiToRaw")
00174                 << "\n The following L1 GT DAQ readout record will be packed.\n"
00175                 << " Some boards could be disabled before packing,"
00176                 << " see detailed board packing.\n" << myCoutStream.str() << "\n"
00177                 << std::endl;
00178     }
00179 
00180     // get GTFE block
00181     L1GtfeWord gtfeBlock = gtReadoutRecord->gtfeWord();
00182 
00183     // get the number of Bx in the event for alternative 0 and alternative 1
00184     cms_uint16_t recordLength0 = gtfeBlock.recordLength();
00185     cms_uint16_t recordLength1 = gtfeBlock.recordLength1();
00186 
00187 
00188     // get list of active boards from the GTFE payload
00189     // and mask some boards, if required
00190     // boards not active are not written to the record
00191 
00192     cms_uint16_t activeBoardsGtInitial = gtfeBlock.activeBoards();
00193     cms_uint16_t altNrBxBoardInitial = gtfeBlock.altNrBxBoard();
00194 
00195     // mask some boards, if needed
00196 
00197     cms_uint16_t activeBoardsGt = activeBoardsGtInitial & m_activeBoardsMaskGt;
00198 
00199     if (m_verbosity && m_isDebugEnabled) {
00200         LogDebug("L1GTDigiToRaw")
00201                 << "\nActive boards before masking(hex format): " << std::hex
00202                 << std::setw(sizeof ( activeBoardsGtInitial ) * 2) << std::setfill('0')
00203                 << activeBoardsGtInitial << std::dec << std::setfill(' ')
00204                 << "Active boards after masking(hex format):  " << std::hex
00205                 << std::setw(sizeof ( activeBoardsGt ) * 2) << std::setfill('0') << activeBoardsGt
00206                 << std::dec << std::setfill(' ') << " \n"
00207                 << std::endl;
00208     }
00209 
00210     // get the size of the record
00211 
00212     unsigned int gtDataSize = 0;
00213 
00214     unsigned int headerSize = 8;
00215     gtDataSize += headerSize;
00216 
00217     for (CItBoardMaps
00218             itBoard = boardMaps.begin();
00219             itBoard != boardMaps.end(); ++itBoard) {
00220 
00221         if (itBoard->gtBoardType() == GTFE) {
00222             gtDataSize += gtfeBlock.getSize();
00223             continue;
00224         }
00225 
00226 
00227         int iActiveBit = itBoard->gtBitDaqActiveBoards();
00228         bool activeBoardToPack = false;
00229 
00230         int altNrBxBoardVal = -1;
00231 
00232         if (iActiveBit >= 0) {
00233             activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
00234 
00235             altNrBxBoardVal = (altNrBxBoardInitial & ( 1 << iActiveBit )) >> iActiveBit;
00236 
00237             if (altNrBxBoardVal == 1) {
00238                 m_totalBxInEvent = recordLength1;
00239             } else if (altNrBxBoardVal == 0) {
00240                 m_totalBxInEvent = recordLength0;
00241             } else {
00242                 if (m_verbosity) {
00243                     edm::LogWarning("L1GTDigiToRaw")
00244                     << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal
00245                     << " for board " << std::hex << ( itBoard->gtBoardId() ) << std::dec
00246                     << "\n  iActiveBit =            " << iActiveBit
00247                     << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial <<  std::dec
00248                     << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt <<  std::dec
00249                     << "\n  activeBoardToPack =   " << activeBoardToPack
00250                     << "\n Set altNrBxBoardVal tentatively to "
00251                     << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
00252                     << std::endl;
00253                 }
00254 
00255                 m_totalBxInEvent = recordLength0;
00256             }
00257 
00258 
00259         } else {
00260             // board not in the ActiveBoards for the record
00261             continue;
00262         }
00263 
00264         if (activeBoardToPack) {
00265 
00266             switch (itBoard->gtBoardType()) {
00267                 case GTFE: {
00268                         // size already added;
00269                     }
00270 
00271                     break;
00272                 case FDL: {
00273                         L1GtFdlWord fdlBlock;
00274                         gtDataSize += m_totalBxInEvent*fdlBlock.getSize();
00275                     }
00276 
00277                     break;
00278                 case PSB: {
00279                         L1GtPsbWord psbBlock;
00280                         gtDataSize += m_totalBxInEvent*psbBlock.getSize();
00281                     }
00282 
00283                     break;
00284                 case GMT: {
00285                         // 17*64/8 TODO FIXME ask Ivan for a getSize() function for GMT record
00286                         unsigned int gmtRecordSize = 136;
00287                         unsigned int gmtCollSize = m_totalBxInEvent*gmtRecordSize;
00288                         gtDataSize += gmtCollSize;
00289                     }
00290 
00291                     break;
00292                 case TCS: {
00293                         L1TcsWord tcsBlock;
00294                         gtDataSize += tcsBlock.getSize();
00295                     }
00296 
00297                     break;
00298                 case TIM: {
00299                         // not considered
00300                     }
00301 
00302                     break;
00303                 default: {
00304                         // do nothing, all blocks are given in GtBoardType enum
00305                     }
00306 
00307                     break;
00308             }
00309         }
00310 
00311     }
00312 
00313 
00314     unsigned int trailerSize = 8;
00315     gtDataSize += trailerSize;
00316 
00317 
00318     // resize, GT raw data record has variable length,
00319     // depending on active boards (read in GTFE)
00320     gtRawData.resize(gtDataSize);
00321 
00322 
00323     // ptrGt: pointer to the beginning of GT record in the raw data
00324 
00325     unsigned char* ptrGt = gtRawData.data();
00326     unsigned char* ptrGtBegin = gtRawData.data();
00327 
00328     if (m_verbosity && m_isDebugEnabled) {
00329         LogDebug("L1GTDigiToRaw") << "\n Size of raw data: " << gtRawData.size() << "\n"
00330                 << std::endl;
00331     }
00332 
00333     // ------- pack boards -------
00334 
00335     // pack header
00336     packHeader(ptrGt, iEvent);
00337     ptrGt += headerSize; // advance with header size
00338 
00339     // loop over other blocks in the raw record, if they are active
00340 
00341     for (CItBoardMaps
00342             itBoard = gtRecordMap.begin();
00343             itBoard != gtRecordMap.end(); ++itBoard) {
00344 
00345         if (itBoard->gtBoardType() == GTFE) {
00346 
00347             packGTFE(evSetup, ptrGt, gtfeBlock, activeBoardsGt);
00348 
00349             if (m_verbosity && m_isDebugEnabled) {
00350 
00351                 std::ostringstream myCoutStream;
00352                 gtfeBlock.print(myCoutStream);
00353                 LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
00354             }
00355 
00356             ptrGt += gtfeBlock.getSize(); // advance with GTFE block size
00357 
00358             continue;
00359         }
00360 
00361 
00362         // pack modules other than GTFE if they are active
00363 
00364         int iActiveBit = itBoard->gtBitDaqActiveBoards();
00365         bool activeBoardToPack = false;
00366 
00367         int altNrBxBoardVal = -1;
00368 
00369         if (iActiveBit >= 0) {
00370             activeBoardToPack = activeBoardsGt & (1 << iActiveBit);
00371 
00372             altNrBxBoardVal = (altNrBxBoardInitial & ( 1 << iActiveBit )) >> iActiveBit;
00373 
00374             if (altNrBxBoardVal == 1) {
00375                 m_totalBxInEvent = recordLength1;
00376             } else if (altNrBxBoardVal == 0) {
00377                 m_totalBxInEvent = recordLength0;
00378             } else {
00379                 if (m_verbosity) {
00380                     edm::LogWarning("L1GTDigiToRaw")
00381                     << "\n\nWARNING: Wrong value altNrBxBoardVal = " << altNrBxBoardVal
00382                     << " for board " << std::hex << ( itBoard->gtBoardId() ) << std::dec
00383                     << "\n  iActiveBit =            " << iActiveBit
00384                     << "\n  altNrBxBoardInitial = 0x" << std::hex << altNrBxBoardInitial <<  std::dec
00385                     << "\n  activeBoardsGt =      0x" << std::hex << activeBoardsGt <<  std::dec
00386                     << "\n  activeBoardToPack =   " << activeBoardToPack
00387                     << "\n Set altNrBxBoardVal tentatively to "
00388                     << recordLength0 << "\n Job may crash or produce wrong results!\n\n"
00389                     << std::endl;
00390                 }
00391 
00392                 m_totalBxInEvent = recordLength0;
00393             }
00394 
00395             m_minBxInEvent = (m_totalBxInEvent + 1)/2 - m_totalBxInEvent;
00396             m_maxBxInEvent = (m_totalBxInEvent + 1)/2 - 1;
00397 
00398 
00399         } else {
00400             // board not in the ActiveBoards for the record
00401             continue;
00402         }
00403 
00404         if (activeBoardToPack) {
00405 
00406             if (m_verbosity && m_isDebugEnabled) {
00407                 LogDebug("L1GTDigiToRaw")
00408                         << "\nBoard " << std::hex << "0x" << ( itBoard->gtBoardId() ) << std::dec
00409                         << "\n  Number of bunch crosses in the record: " << m_totalBxInEvent
00410                         << " = " << "[" << m_minBxInEvent << ", " << m_maxBxInEvent
00411                         << "] BX\n"
00412                         << std::endl;
00413             }
00414 
00415             // active board, pack it
00416             switch (itBoard->gtBoardType()) {
00417 
00418                 case FDL: {
00419 
00420                     for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
00421 
00422                         L1GtFdlWord fdlBlock = gtReadoutRecord->gtFdlWord(iBxInEvent);
00423                         packFDL(evSetup, ptrGt, fdlBlock);
00424 
00425                         if (m_verbosity && m_isDebugEnabled) {
00426 
00427                             std::ostringstream myCoutStream;
00428                             fdlBlock.print(myCoutStream);
00429                             LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
00430                         }
00431 
00432                         ptrGt += fdlBlock.getSize(); // advance with FDL block size
00433                     }
00434 
00435                 }
00436                     break;
00437                 case PSB: {
00438 
00439                     if (m_verbosity && m_isDebugEnabled) {
00440                         LogDebug("L1GTDigiToRaw") << "\nBoard of type " << itBoard->gtBoardName()
00441                                 << " with index " << itBoard->gtBoardIndex() << " and boardId "
00442                                 << std::hex << itBoard->gtBoardId() << std::dec << "\n"
00443                                 << std::endl;
00444                     }
00445 
00446                     for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent; ++iBxInEvent) {
00447 
00448                         L1GtPsbWord psbBlock = gtReadoutRecord->gtPsbWord(
00449                                 itBoard->gtBoardId(), iBxInEvent);
00450 
00451                         packPSB(evSetup, ptrGt, psbBlock);
00452 
00453                         if (m_verbosity && m_isDebugEnabled) {
00454 
00455                             std::ostringstream myCoutStream;
00456                             psbBlock.print(myCoutStream);
00457                             LogTrace("L1GTDigiToRaw") << myCoutStream.str() << "\n" << std::endl;
00458                         }
00459 
00460                         ptrGt += psbBlock.getSize(); // advance with PSB block size
00461                     }
00462 
00463                 }
00464                     break;
00465                 case GMT: {
00466 
00467                     // get GMT record TODO separate GMT record or via RefProd from GT record
00468                     edm::Handle<L1MuGMTReadoutCollection> gmtrc_handle;
00469                     iEvent.getByLabel(m_muGmtInputTag, gmtrc_handle);
00470                     if (!gmtrc_handle.isValid()) {
00471                         if (m_verbosity) {
00472                             edm::LogWarning("L1GTDigiToRaw")
00473                                     << "\nWarning: L1MuGMTReadoutCollection with input tag "
00474                                     << m_muGmtInputTag
00475                                     << "\nrequested in configuration, but not found in the event."
00476                                     << "\nQuit packing this event" << std::endl;
00477                         }
00478 
00479                         std::auto_ptr<FEDRawDataCollection> allFedRawData(new FEDRawDataCollection);
00480 
00481                         // put the raw data in the event
00482                         iEvent.put(allFedRawData);
00483 
00484                         return;
00485                     }
00486 
00487                     L1MuGMTReadoutCollection const* gmtrc = gmtrc_handle.product();
00488 
00489                     // pack the GMT record
00490 
00491                     unsigned int gmtCollSize = 0;
00492                     gmtCollSize = packGmtCollection(ptrGt, gmtrc);
00493                     ptrGt += gmtCollSize; // advance with GMT collection size
00494 
00495                 }
00496                     break;
00497                 default: {
00498 
00499                     // do nothing, all blocks are given in GtBoardType enum
00500                     break;
00501                 }
00502             }
00503 
00504         }
00505     }
00506 
00507     // pack trailer
00508     packTrailer(ptrGt, ptrGtBegin, gtDataSize);
00509 
00510     // put the raw data in the event
00511     iEvent.put(allFedRawData);
00512 }
00513 
00514 
00515 // pack header
00516 void L1GTDigiToRaw::packHeader(unsigned char* ptrGt, edm::Event& iEvent) {
00517     // TODO FIXME where from to get all numbers?
00518 
00519     // Event Trigger type identifier
00520     int triggerTypeVal = 0;
00521 
00522     // Level-1 event number generated by the TTC system
00523     int lvl1IdVal = iEvent.id().event();
00524 
00525     // The bunch crossing number
00526     int bxCross = iEvent.bunchCrossing();
00527     cms_uint16_t bxCrossHw = 0;
00528     if ( ( bxCross & 0xFFF ) == bxCross) {
00529         bxCrossHw = static_cast<cms_uint16_t> (bxCross);
00530     } else {
00531         bxCrossHw = 0; // Bx number too large, set to 0!
00532         if (m_verbosity && m_isDebugEnabled) {
00533             LogDebug("L1GTDigiToRaw") << "\nBunch cross number [hex] = " << std::hex << bxCross
00534                     << "\n  larger than 12 bits. Set to 0! \n" << std::dec << std::endl;
00535         }
00536     }
00537     int bxIdVal = bxCrossHw;
00538 
00539     // Identifier of the FED
00540     int sourceIdVal = m_daqGtFedId;
00541 
00542     // Version identifier of the FED data format
00543     int versionVal = 0;
00544 
00545     // 0 -> the current header word is the last one.
00546     // 1-> other header words can follow
00547     // (always 1 for ECAL)
00548     bool moreHeadersVal = false;
00549 
00550     FEDHeader gtFEDHeader(ptrGt);
00551 
00552     gtFEDHeader.set(
00553             ptrGt, triggerTypeVal, lvl1IdVal, bxIdVal, sourceIdVal, versionVal, moreHeadersVal);
00554 
00555 }
00556 
00557 // pack the GTFE block
00558 void L1GTDigiToRaw::packGTFE(
00559         const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtfeWord& gtfeBlock,
00560         cms_uint16_t activeBoardsGtValue) {
00561 
00562     if (m_verbosity && m_isDebugEnabled) {
00563         LogDebug("L1GTDigiToRaw") << "\nPacking GTFE \n" << std::endl;
00564     }
00565 
00566     int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
00567 
00568     // initialize the required number of word64
00569     int nrWord64 = gtfeBlock.getSize() / uLength;
00570     std::vector<cms_uint64_t> tmpWord64;
00571     tmpWord64.resize(nrWord64);
00572 
00573     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00574         tmpWord64[iWord] = 0x0000000000000000ULL;
00575     }
00576 
00577     // fill the values in the words
00578     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00579 
00580         gtfeBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
00581         gtfeBlock.setRecordLength1Word64(tmpWord64[iWord], iWord);
00582         gtfeBlock.setRecordLengthWord64(tmpWord64[iWord], iWord);
00583         gtfeBlock.setBxNrWord64(tmpWord64[iWord], iWord);
00584         gtfeBlock.setSetupVersionWord64(tmpWord64[iWord], iWord);
00585         gtfeBlock.setActiveBoardsWord64(tmpWord64[iWord], iWord, activeBoardsGtValue);
00586         gtfeBlock.setAltNrBxBoardWord64(tmpWord64[iWord], iWord);
00587         gtfeBlock.setTotalTriggerNrWord64(tmpWord64[iWord], iWord);
00588 
00589     }
00590 
00591     // put the words in the FED record
00592 
00593     cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*> (const_cast<unsigned char*> (ptrGt));
00594 
00595     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00596 
00597         *pw++ = tmpWord64[iWord];
00598 
00599         if (m_verbosity && m_isDebugEnabled) {
00600             LogTrace("L1GTDigiToRaw")
00601                     << std::setw(4) << iWord << "  "
00602                     << std::hex << std::setfill('0') << std::setw(16) << tmpWord64[iWord] << std::dec
00603                     << std::setfill(' ')
00604                     << std::endl;
00605         }
00606     }
00607 
00608 }
00609 
00610 
00611 // pack the FDL block
00612 void L1GTDigiToRaw::packFDL(
00613         const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtFdlWord& fdlBlock) {
00614 
00615     if (m_verbosity && m_isDebugEnabled) {
00616 
00617         LogDebug("L1GTDigiToRaw") << "\nPacking FDL \n" << std::endl;
00618     }
00619 
00620     int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
00621 
00622     // initialize the required number of word64
00623     int nrWord64 = fdlBlock.getSize() / uLength;
00624     std::vector<cms_uint64_t> tmpWord64;
00625     tmpWord64.resize(nrWord64);
00626 
00627     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00628         tmpWord64[iWord] = 0x0000000000000000ULL;
00629     }
00630 
00631     // fill the values in the words
00632     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00633 
00634         fdlBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
00635         fdlBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
00636         fdlBlock.setBxNrWord64(tmpWord64[iWord], iWord);
00637         fdlBlock.setEventNrWord64(tmpWord64[iWord], iWord);
00638 
00639         fdlBlock.setGtTechnicalTriggerWordWord64(tmpWord64[iWord], iWord);
00640 
00641         fdlBlock.setGtDecisionWordAWord64(tmpWord64[iWord], iWord);
00642         fdlBlock.setGtDecisionWordBWord64(tmpWord64[iWord], iWord);
00643 
00644         fdlBlock.setGtDecisionWordExtendedWord64(tmpWord64[iWord], iWord);
00645 
00646         fdlBlock.setPhysicsDeclaredWord64(tmpWord64[iWord], iWord);
00647         fdlBlock.setGtPrescaleFactorIndexTechWord64(tmpWord64[iWord], iWord);
00648         fdlBlock.setGtPrescaleFactorIndexAlgoWord64(tmpWord64[iWord], iWord);
00649         fdlBlock.setNoAlgoWord64(tmpWord64[iWord], iWord);
00650         fdlBlock.setFinalORWord64(tmpWord64[iWord], iWord);
00651 
00652         fdlBlock.setOrbitNrWord64(tmpWord64[iWord], iWord);
00653         fdlBlock.setLumiSegmentNrWord64(tmpWord64[iWord], iWord);
00654         fdlBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
00655 
00656     }
00657 
00658     // put the words in the FED record
00659 
00660     cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*> (const_cast<unsigned char*> (ptrGt));
00661 
00662     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00663 
00664         *pw++ = tmpWord64[iWord];
00665 
00666         if (m_verbosity && m_isDebugEnabled) {
00667 
00668             LogTrace("L1GTDigiToRaw")
00669                     << std::setw(4) << iWord << "  "
00670                     << std::hex << std::setfill('0') << std::setw(16) << tmpWord64[iWord] << std::dec
00671                     << std::setfill(' ')
00672                     << std::endl;
00673         }
00674     }
00675 
00676 }
00677 
00678 // pack the PSB block
00679 void L1GTDigiToRaw::packPSB(
00680         const edm::EventSetup& evSetup, unsigned char* ptrGt, L1GtPsbWord& psbBlock) {
00681     if (m_verbosity && m_isDebugEnabled) {
00682 
00683         LogDebug("L1GTDigiToRaw") << "\nPacking PSB \n" << std::endl;
00684     }
00685 
00686     int uLength = L1GlobalTriggerReadoutSetup::UnitLength;
00687 
00688     // initialize the required number of word64
00689     int nrWord64 = psbBlock.getSize() / uLength;
00690     std::vector<cms_uint64_t> tmpWord64;
00691     tmpWord64.resize(nrWord64);
00692 
00693     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00694         tmpWord64[iWord] = 0x0000000000000000ULL;
00695     }
00696 
00697     // fill the values in the words
00698     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00699 
00700         psbBlock.setBoardIdWord64(tmpWord64[iWord], iWord);
00701         psbBlock.setBxInEventWord64(tmpWord64[iWord], iWord);
00702         psbBlock.setBxNrWord64(tmpWord64[iWord], iWord);
00703         psbBlock.setEventNrWord64(tmpWord64[iWord], iWord);
00704 
00705         psbBlock.setADataWord64(tmpWord64[iWord], iWord);
00706         psbBlock.setBDataWord64(tmpWord64[iWord], iWord);
00707 
00708         psbBlock.setLocalBxNrWord64(tmpWord64[iWord], iWord);
00709 
00710     }
00711 
00712     // put the words in the FED record
00713 
00714     cms_uint64_t* pw = reinterpret_cast<cms_uint64_t*> (const_cast<unsigned char*> (ptrGt));
00715 
00716     for (int iWord = 0; iWord < nrWord64; ++iWord) {
00717 
00718         *pw++ = tmpWord64[iWord];
00719 
00720         if (m_verbosity && m_isDebugEnabled) {
00721 
00722             LogTrace("L1GTDigiToRaw")
00723                     << std::setw(4) << iWord << "  "
00724                     << std::hex << std::setfill('0') << std::setw(16) << tmpWord64[iWord] << std::dec
00725                     << std::setfill(' ')
00726                     << std::endl;
00727         }
00728     }
00729 
00730 }
00731 
00732 // pack the GMT collection using packGMT (GMT record packing)
00733 unsigned int L1GTDigiToRaw::packGmtCollection(
00734     unsigned char* ptrGt,
00735     L1MuGMTReadoutCollection const* digis)
00736 {
00737 
00738     if (m_verbosity && m_isDebugEnabled) {
00739         LogDebug("L1GTDigiToRaw") << "\nPacking GMT collection \n" << std::endl;
00740     }
00741 
00742     unsigned gmtsize = 0;
00743 
00744     // loop range: int m_totalBxInEvent is normally even (L1A-1, L1A, L1A+1, with L1A = 0)
00745     for (int iBxInEvent = m_minBxInEvent; iBxInEvent <= m_maxBxInEvent;
00746             ++iBxInEvent) {
00747         L1MuGMTReadoutRecord const& gmtrr = digis->getRecord(iBxInEvent);
00748         gmtsize = packGMT(gmtrr, ptrGt);
00749         ptrGt += gmtsize;
00750     }
00751 
00752     return m_totalBxInEvent*gmtsize;
00753 
00754 }
00755 
00756 // pack a GMT record
00757 unsigned L1GTDigiToRaw::packGMT(L1MuGMTReadoutRecord const& gmtrr, unsigned char* chp)
00758 {
00759 
00760     const unsigned SIZE=136;
00761     const unsigned boardId=0xdd12;
00762     memset(chp,0,SIZE);
00763 
00764     unsigned* p = (unsigned*) chp;
00765 
00766     // event number + bcerr
00767     *p++ = (gmtrr.getEvNr()&0xffffff) | ((gmtrr.getBCERR()&0xff)<<24);
00768     // bx number, bx in event, length(?), board-id(?)
00769     *p++ = (gmtrr.getBxNr()&0xfff) | ((gmtrr.getBxInEvent()&0xf)<<12) | (boardId<<16);
00770 
00771     std::vector<L1MuRegionalCand> vrc;
00772     std::vector<L1MuRegionalCand>::const_iterator irc;
00773     unsigned* pp = p;
00774 
00775     vrc = gmtrr.getDTBXCands();
00776     pp = p;
00777     for(irc=vrc.begin(); irc!=vrc.end(); irc++) {
00778         *pp++ = (*irc).getDataWord();
00779     }
00780     p+=4;
00781 
00782     vrc = gmtrr.getBrlRPCCands();
00783     pp = p;
00784     for(irc=vrc.begin(); irc!=vrc.end(); irc++) {
00785         *pp++ = (*irc).getDataWord();
00786     }
00787     p+=4;
00788 
00789     vrc = gmtrr.getCSCCands();
00790     pp = p;
00791     for(irc=vrc.begin(); irc!=vrc.end(); irc++) {
00792         *pp++ = (*irc).getDataWord();
00793     }
00794     p+=4;
00795 
00796     vrc = gmtrr.getFwdRPCCands();
00797     pp = p;
00798     for(irc=vrc.begin(); irc!=vrc.end(); irc++) {
00799         *pp++ = (*irc).getDataWord();
00800     }
00801     p+=4;
00802 
00803     // the regional candidates are written to the record with inverted Pt and qual bits
00804     pp = p-16;
00805     for(int i=0; i<16; i++) {
00806         unsigned w = *pp;
00807         *pp++ = (w&0xffff00ff) | ((~w)&0x0000ff00);
00808     }
00809 
00810     std::vector<L1MuGMTExtendedCand> vgc;
00811     std::vector<L1MuGMTExtendedCand>::const_iterator igc;
00812 
00813     vgc = gmtrr.getGMTBrlCands();
00814     pp = p;
00815     for(igc=vgc.begin(); igc!=vgc.end(); igc++) {
00816         *pp++ = (*igc).getDataWord();
00817     }
00818     p+=4;
00819 
00820     vgc = gmtrr.getGMTFwdCands();
00821     pp = p;
00822     for(igc=vgc.begin(); igc!=vgc.end(); igc++) {
00823         *pp++ = (*igc).getDataWord();
00824     }
00825     p+=4;
00826 
00827     vgc = gmtrr.getGMTCands();
00828     pp = p;
00829     for(igc=vgc.begin(); igc!=vgc.end(); igc++) {
00830         *pp++ = (*igc).getDataWord();
00831     }
00832     p+=4;
00833 
00834     unsigned char* chpp;
00835 
00836     vgc = gmtrr.getGMTBrlCands();
00837     chpp = (unsigned char*) p;
00838     for(igc=vgc.begin(); igc!=vgc.end(); igc++) {
00839         *chpp++ = (*igc).rank();
00840     }
00841     p++;
00842 
00843     vgc = gmtrr.getGMTFwdCands();
00844     chpp = (unsigned char*) p;
00845     for(igc=vgc.begin(); igc!=vgc.end(); igc++) {
00846         *chpp++ = (*igc).rank();
00847     }
00848     p++;
00849 
00850     return SIZE;
00851 }
00852 
00853 unsigned int L1GTDigiToRaw::flipPtQ(unsigned int w)
00854 {
00855     return ( (w&0xffff00ff) | ((~w)&0x0000ff00) );
00856 }
00857 
00858 // pack trailer
00859 void L1GTDigiToRaw::packTrailer(unsigned char* ptrGt, unsigned char* ptrGtBegin, int dataSize) {
00860 
00861     // TODO FIXME where from to get all numbers?
00862 
00863     // The length of the event fragment counted in 64-bit words including header and trailer
00864     int lengthVal = dataSize / 8;
00865 
00866     // Cyclic Redundancy Code of the event fragment including header and trailer
00867     int crcVal = evf::compute_crc(ptrGtBegin, dataSize);
00868 
00869     // Event fragment status information
00870     int evtStatusVal = 0;
00871 
00872     // Current value of the Trigger Throttling System bits.
00873     int ttsBitsVal = 0;
00874 
00875     // 0 -> the current trailer word is the last one.
00876     // 1-> other trailer words can follow
00877     // (always 0 for ECAL)
00878     bool moreTrailersVal = false;
00879 
00880     FEDTrailer gtFEDTrailer(ptrGt);
00881     gtFEDTrailer.set(ptrGt, lengthVal, crcVal, evtStatusVal, ttsBitsVal, moreTrailersVal);
00882 
00883 }
00884 
00885 
00886 //
00887 void L1GTDigiToRaw::endJob()
00888 {
00889 
00890     // empty now
00891 }
00892 
00893 
00894 // static class members