Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:05

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h"
0003 
0004 #include "GTCollections.h"
0005 #include "GlobalAlgBlkUnpacker.h"
0006 
0007 namespace l1t {
0008   namespace stage2 {
0009     bool GlobalAlgBlkUnpacker::unpack(const Block& block, UnpackerCollections* coll) {
0010       LogDebug("L1T") << "AMCNo " << block.amc().getAMCNumber() << " Block ID  = " << block.header().getID()
0011                       << " size = " << block.header().getSize();
0012 
0013       // ================================================================================
0014       //Should this be configured someplace?
0015       unsigned int wdPerBX = 6;
0016       unsigned int initialBlkID = 33;  //first block of inital alg bits
0017       unsigned int intermBlkID = 39;   //first block of alg bits after intermediate step
0018       unsigned int finalBlkID = 45;    //first block of final alg bits
0019       // ================================================================================
0020 
0021       unsigned int uGTBoard = block.amc().getAMCNumber() - 1;
0022 
0023       int nBX =
0024           int(ceil(block.header().getSize() / 6.));  // FOR GT Not sure what we have here...put at 6 because of 6 frames
0025 
0026       // Find the central, first and last BXs
0027       int firstBX = -(ceil((double)nBX / 2.) - 1);
0028       int lastBX;
0029       if (nBX % 2 == 0) {
0030         lastBX = ceil((double)nBX / 2.);
0031       } else {
0032         lastBX = ceil((double)nBX / 2.) - 1;
0033       }
0034 
0035       auto res_ = static_cast<GTCollections*>(coll)->getAlgs();
0036       res_->setBXRange(firstBX, lastBX);
0037 
0038       LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX << endl;
0039 
0040       // Loop over multiple BX and then number of EG cands filling collection
0041       int numBX = 0;  //positive int to count BX
0042       for (int bx = firstBX; bx <= lastBX; bx++) {
0043         // If this is the first block on first board, instantiate GlobalAlg so it is there to fill from mult. blocks
0044         if (block.header().getID() == initialBlkID && uGTBoard == 0) {
0045           LogDebug("L1T") << "Creating GT Algorithm Block for BX =" << bx << std::endl;
0046           GlobalAlgBlk talg = GlobalAlgBlk();
0047           res_->push_back(bx, talg);
0048         }
0049 
0050         //fetch
0051         GlobalAlgBlk alg = res_->at(bx, 0);
0052 
0053         //Determine offset of algorithm bits based on block.ID
0054         // ID=initialBlkID    offset = 0;  ID=initialBlkID+2    offset=192;  ID=initialBlkID+4    offset=384=2*192; (before prescale)
0055         // ID=intermBlkID  offset = 0;  ID=intermBlkID+2  offset=192;  ID=intermBlkID+4  offset=384=2*192; (after prescale)
0056         // ID=finalBlkID      offset = 0;  ID=finalBlkID+2      offset=192;  ID=finalBlkID+4      offset=384=2*192; (after mask (Final))
0057         int algOffset = (block.header().getID() - initialBlkID + 1) / 2;
0058         algOffset = (algOffset % 3) * 192;
0059 
0060         for (unsigned int wd = 0; wd < wdPerBX; wd++) {
0061           uint32_t raw_data = block.payload()[wd + numBX * wdPerBX];
0062           LogDebug("L1T") << "BX " << bx << " payload word " << wd << " 0x" << hex << raw_data << " offset=" << dec
0063                           << algOffset << std::endl;
0064 
0065           //parse these 32 bits into algorithm bits (perhaps needs a more efficient way of doing this?
0066           if ((block.header().getID() != initialBlkID + 4 && block.header().getID() != intermBlkID + 4 &&
0067                block.header().getID() != finalBlkID + 4) ||
0068               wd < 4) {
0069             for (unsigned int bt = 0; bt < 32; bt++) {
0070               int val = ((raw_data >> bt) & 0x1);
0071               unsigned int algBit = bt + wd * 32 + algOffset;
0072 
0073               if (val == 1 && algBit < alg.maxPhysicsTriggers) {
0074                 LogDebug("L1T") << "Found valid alg bit (" << algBit << ") on bit (" << bt << ") word (" << wd
0075                                 << ") algOffset (" << algOffset << ") block ID (" << block.header().getID() << ")"
0076                                 << " Board# " << uGTBoard << std::endl;
0077                 if (block.header().getID() < initialBlkID + 5) {
0078                   alg.setAlgoDecisionInitial(algBit, true);
0079                 } else if (block.header().getID() < intermBlkID + 5) {
0080                   alg.setAlgoDecisionInterm(algBit, true);
0081                 } else {
0082                   alg.setAlgoDecisionFinal(algBit, true);
0083                 }
0084               } else if (val == 1) {
0085                 LogDebug("L1T") << "Found invalid alg bit (" << algBit << ") out of range on bit (" << bt << ") word ("
0086                                 << wd << ") algOffset (" << algOffset << ") block ID (" << block.header().getID() << ")"
0087                                 << std::endl;
0088               }
0089             }
0090 
0091           } else if (block.header().getID() == initialBlkID + 4 && (wd == 4 || wd == 5)) {
0092             //This is the 32bit hash of menu name
0093             if (wd == 4)
0094               alg.setL1MenuUUID(raw_data);
0095             //This is the 32bit hash of menu firmware uuid
0096             if (wd == 5)
0097               alg.setL1FirmwareUUID(raw_data);
0098 
0099           } else if (block.header().getID() == finalBlkID + 4 && wd == 4) {
0100             //Get the local FINORs and Veto...Global FINOR calculated below
0101             if ((raw_data & 0x100) >> 8)
0102               alg.setFinalORVeto(true);
0103             if ((raw_data & 0x1) >> 0)
0104               alg.setFinalORPreVeto(true);
0105             LogDebug("L1T") << " Packing the FinalOR " << wd << " 0x" << hex << raw_data << endl;
0106           } else if (block.header().getID() == finalBlkID + 4 && wd == 5) {
0107             //This is the Prescale Column
0108             alg.setPreScColumn(raw_data & 0xFF);
0109             LogDebug("L1T") << " Packing the Prescale Column " << wd << " 0x" << hex << raw_data << endl;
0110           }
0111         }
0112 
0113         //Redetermine Final (multiboard)  FINOR
0114         if (alg.getFinalORPreVeto() & !alg.getFinalORVeto()) {
0115           alg.setFinalOR(true);
0116         } else {
0117           alg.setFinalOR(false);  //be explicit and must set to false if we find a board with veto set.
0118         }
0119 
0120         // Put the object back into place (Must be better way)
0121         res_->set(bx, 0, alg);
0122 
0123         //alg.print(std::cout);
0124 
0125         //increment counter of which BX we are processing
0126         numBX++;
0127       }
0128 
0129       return true;
0130     }
0131   }  // namespace stage2
0132 }  // namespace l1t
0133 
0134 DEFINE_L1T_UNPACKER(l1t::stage2::GlobalAlgBlkUnpacker);