Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:49

0001 #include "BMTFPackerInputs.h"
0002 
0003 #include <vector>
0004 //#include <bitset>//debug
0005 
0006 namespace l1t {
0007   namespace stage2 {
0008 
0009     const int BMTFPackerInputs::ownLinks_[] = {4, 5, 12, 13, 20, 21, 22, 23, 28, 29};
0010 
0011     Blocks BMTFPackerInputs::pack(const edm::Event& event, const PackerTokens* toks) {
0012       int board_id = (int)board();
0013 
0014       auto muonPhToken = static_cast<const BMTFTokens*>(toks)->getInputMuonTokenPh();
0015       auto muonThToken = static_cast<const BMTFTokens*>(toks)->getInputMuonTokenTh();
0016 
0017       Blocks blocks;
0018 
0019       edm::Handle<L1MuDTChambPhContainer> phInputs;
0020       event.getByToken(muonPhToken, phInputs);
0021       edm::Handle<L1MuDTChambThContainer> thInputs;
0022       event.getByToken(muonThToken, thInputs);
0023 
0024       uint32_t qualEta_32bit = 0;
0025       uint32_t posEta_0_32bit = 0;
0026       uint32_t posEta_n2_32bit = 0, posEta_n1_32bit = 0;
0027       uint32_t posEta_p2_32bit = 0, posEta_p1_32bit = 0;
0028 
0029       bool moreBXeta = false;
0030       for (int link = 0; link <= 35; link++) {
0031         //    std::cout << "link : " << link << std::endl;
0032 
0033         if ((link >= 6 && link < 8) || (link >= 14 && link < 16) || (link >= 30 && link < 32))
0034           continue;
0035 
0036         //initializing null block_payloads and block_id
0037         std::vector<uint32_t> payload_0(6, 0);
0038         std::vector<uint32_t> payload_p1(6, 0);
0039         std::vector<uint32_t> payload_n1(6, 0);
0040         std::vector<uint32_t> payload_p2(6, 0);
0041         std::vector<uint32_t> payload_n2(6, 0);
0042 
0043         unsigned int block_id = 2 * link;
0044 
0045         std::vector<bool> bxPresent(5, false);
0046         bool moreBXphi = false;
0047 
0048         unsigned int BC = 0;
0049 
0050         //The first 4 phi words for the link's payload
0051 
0052         for (const auto& iphi : *(phInputs->getContainer())) {
0053           // Only allow -2 <= bxNum <= 2, as in Stage2 data
0054           if (std::abs(iphi.bxNum()) > 2)
0055             continue;
0056 
0057           if (iphi.bxNum() != 0)
0058             moreBXphi = true;
0059 
0060           //          std::cout << "scNum+1 = " << iphi->scNum()+1 << ",   board_id = " << board_id << std::endl;
0061           //          std::cout << "bx, station = " << iphi->bxNum() << ", " << iphi->stNum() << std::endl;
0062 
0063           //BC = iphi->BxCnt();//this thing here is not completely functional
0064 
0065           if (iphi.scNum() + 1 != board_id)
0066             continue;
0067           //          std::cout << "correct board" << std::endl;
0068 
0069           if (link != ownLinks_[4 + 2 * (iphi.whNum()) + iphi.Ts2Tag()])
0070             continue;
0071           //          std::cout << "correct link" << std::endl;
0072 
0073           bxPresent[2 + iphi.bxNum()] = true;
0074 
0075           //1 create 32word, 2 insert 32word in correct Block Slot
0076           uint32_t word_32bit = wordPhMaker(iphi);  //1
0077           if (bxPresent[0]) {
0078             payload_n2[iphi.stNum() - 1] = word_32bit;
0079           } else if (bxPresent[1]) {
0080             payload_n1[iphi.stNum() - 1] = word_32bit;
0081           } else if (bxPresent[2])
0082             payload_0[iphi.stNum() - 1] = word_32bit;
0083           else if (bxPresent[3]) {
0084             payload_p1[iphi.stNum() - 1] = word_32bit;
0085           } else if (bxPresent[4]) {
0086             payload_p2[iphi.stNum() - 1] = word_32bit;
0087           }
0088 
0089           bxPresent.assign(5, false);
0090 
0091         }  //phiCont_itr
0092 
0093         //============================================================================================
0094 
0095         //Create phiNull words (use the old format for null words because Packer gives fw_id=1)
0096         //uint32_t phiNull_32bit = 0 | (BC & 0x3) << 30 | (7 & 0x7) << 22; //for the new fw
0097         uint32_t phiNull_32bit = 0 | (BC & 0x3) << 30;  //for the old fw
0098         //phiNull = (BC)000001110000000000000000000000
0099         uint32_t etaNull_32bit = 0 | (BC & 0x3) << 30;
0100         //etaNull = (BC)000000000000000000000000000000
0101 
0102         //============================================================================================
0103 
0104         //The 5th & 6th words of the link's payload
0105         //    std::cout << "link%2 = " << link%2 << std::endl;
0106         if (link % 2 == 0) {
0107           //these Eta vars have to be declared out of link itr scope in order to maintain its information for the next link
0108           //Using these as the basis for the pos and qual 32bit eta word
0109           //in case there are les than 3 hits, the entries will be zero.
0110           posEta_0_32bit = etaNull_32bit;
0111           posEta_n2_32bit = etaNull_32bit;
0112           posEta_n1_32bit = etaNull_32bit;
0113           posEta_p2_32bit = etaNull_32bit;
0114           posEta_p1_32bit = etaNull_32bit;
0115 
0116           qualEta_32bit = etaNull_32bit;
0117 
0118           for (const auto& ithe : *(thInputs->getContainer())) {
0119             // Only allow -2 <= bxNum <= 2, as in Stage2 data
0120             if (std::abs(ithe.bxNum()) > 2)
0121               continue;
0122 
0123             if (ithe.bxNum() != 0)
0124               moreBXeta = true;
0125 
0126             //debug
0127             //      std::cout << "scNum+1 = " << ithe.scNum()+1 << ",   board_id = " << board_id << std::endl;
0128             //      std::cout << "bx, station = " << ithe.bxNum() << ", " << ithe.stNum() << std::endl;
0129             //      std::cout << "related link: " << ownLinks_[4+2*(ithe.whNum())] << std::endl;
0130 
0131             if (ithe.scNum() + 1 != board_id)
0132               continue;
0133 
0134             if (link != ownLinks_[4 + 2 * (ithe.whNum())])
0135               continue;
0136 
0137             bxPresent[2 + ithe.bxNum()] = true;
0138 
0139             //positions for the next link
0140             uint32_t posEta_7bit = wordThMaker(ithe, false);
0141 
0142             //qualities for this link
0143             uint32_t qualEta_7bit = wordThMaker(ithe, true);
0144             qualEta_32bit = qualEta_32bit | ((qualEta_7bit & 0x7F) << 7 * (ithe.stNum() - 1));
0145 
0146             //write the eta-pos and eta-qual information at the correct payload per BX
0147             if (bxPresent[0]) {
0148               payload_n2[4] = qualEta_32bit;
0149               payload_n2[5] = etaNull_32bit | (2 & 0x2);
0150               posEta_n2_32bit = posEta_n2_32bit | ((posEta_7bit & 0x7F) << 7 * (ithe.stNum() - 1));
0151             } else if (bxPresent[1]) {
0152               payload_n1[4] = qualEta_32bit;
0153               payload_n1[5] = etaNull_32bit | (2 & 0x2);
0154               posEta_n1_32bit = posEta_n1_32bit | ((posEta_7bit & 0x7F) << 7 * (ithe.stNum() - 1));
0155             } else if (bxPresent[2]) {
0156               payload_0[4] = qualEta_32bit;
0157               payload_0[5] = etaNull_32bit | (2 & 0x2);
0158               posEta_0_32bit = posEta_0_32bit | ((posEta_7bit & 0x7F) << 7 * (ithe.stNum() - 1));
0159             } else if (bxPresent[3]) {
0160               payload_p1[4] = qualEta_32bit;
0161               payload_p1[5] = etaNull_32bit | (2 & 0x2);
0162               posEta_p1_32bit = posEta_p1_32bit | ((posEta_7bit & 0x7F) << 7 * (ithe.stNum() - 1));
0163             } else if (bxPresent[4]) {
0164               payload_p2[4] = qualEta_32bit;
0165               payload_p2[5] = etaNull_32bit | (2 & 0x2);
0166               posEta_p2_32bit = posEta_p2_32bit | ((posEta_7bit & 0x7F) << 7 * (ithe.stNum() - 1));
0167             }
0168 
0169             bxPresent.assign(5, false);
0170 
0171           }  //theCont_itr
0172 
0173         } else {  //now that we are in the next prime link #, write the buffered eta-qual
0174 
0175           if (moreBXeta) {
0176             payload_n2[4] = posEta_n2_32bit;
0177             payload_n2[5] = etaNull_32bit;
0178 
0179             payload_n1[4] = posEta_n1_32bit;
0180             payload_n1[5] = etaNull_32bit;
0181           }
0182 
0183           payload_0[4] = posEta_0_32bit;
0184           payload_0[5] = etaNull_32bit;
0185 
0186           if (moreBXeta) {
0187             payload_p1[4] = posEta_p1_32bit;
0188             payload_p1[5] = etaNull_32bit;
0189 
0190             payload_p2[4] = posEta_p2_32bit;
0191             payload_p2[5] = etaNull_32bit;
0192           }
0193         }
0194 
0195         //std::cout << "moreBXphi" << moreBXphi << std::endl;
0196         //std::cout << "moreBXeta" << moreBXeta << std::endl;
0197 
0198         bool moreBX = moreBXphi || moreBXeta;
0199         //std::cout << "moreBX" << moreBX << std::endl;
0200 
0201         //case where phi words are notcreated
0202         for (int iSt = 0; iSt <= 3; iSt++) {
0203           if (moreBX && payload_n2[iSt] == 0)
0204             payload_n2[iSt] = phiNull_32bit;
0205 
0206           if (moreBX && payload_n1[iSt] == 0)
0207             payload_n1[iSt] = phiNull_32bit;
0208 
0209           if (payload_0[iSt] == 0)
0210             payload_0[iSt] = phiNull_32bit;
0211 
0212           if (moreBX && payload_p1[iSt] == 0)
0213             payload_p1[iSt] = phiNull_32bit;
0214 
0215           if (moreBX && payload_p2[iSt] == 0)
0216             payload_p2[iSt] = phiNull_32bit;
0217         }
0218 
0219         //case where eta words are notcreated
0220         for (int word = 4; word <= 5; word++) {
0221           if (moreBX && payload_n2[word] == 0)
0222             payload_n2[word] = etaNull_32bit;
0223 
0224           if (moreBX && payload_n1[word] == 0)
0225             payload_n1[word] = etaNull_32bit;
0226 
0227           if (payload_0[word] == 0)
0228             payload_0[word] = etaNull_32bit;
0229 
0230           if (moreBX && payload_p1[word] == 0)
0231             payload_p1[word] = etaNull_32bit;
0232 
0233           if (moreBX && payload_p2[word] == 0)
0234             payload_p2[word] = etaNull_32bit;
0235         }
0236 
0237         //============================================================================================
0238 
0239         /*
0240 
0241       //debug
0242       std::cout << "payload created : " << std::endl;
0243       if (moreBX){      
0244         for (auto &word : payload_n2)   // 
0245           std::cout << std::bitset<32>(word).to_string() << std::endl;
0246       
0247         for (auto &word : payload_n1)   // 
0248           std::cout << std::bitset<32>(word).to_string() << std::endl;
0249       }
0250       
0251       for (auto &word : payload_0)  // 
0252         std::cout << std::bitset<32>(word).to_string() << std::endl;
0253       
0254       if (moreBX){
0255         for (auto &word : payload_p1)   // 
0256           std::cout << std::bitset<32>(word).to_string() << std::endl;
0257       
0258         for (auto &word : payload_p2)   // 
0259           std::cout << std::bitset<32>(word).to_string() << std::endl;
0260       }
0261       */
0262         //============================================================================================
0263 
0264         std::vector<uint32_t> payload;
0265 
0266         if (moreBX) {  //push -2,-1 bx payloads
0267           for (int i = 0; i < 6; i++)
0268             payload.push_back(payload_n2[i]);
0269           for (int i = 0; i < 6; i++)
0270             payload.push_back(payload_n1[i]);
0271         }
0272 
0273         for (int i = 0; i < 6; i++)  //zero bx payload
0274           payload.push_back(payload_0[i]);
0275 
0276         if (moreBX) {  //push +1,+2 bx payloads
0277           for (int i = 0; i < 6; i++)
0278             payload.push_back(payload_p1[i]);
0279           for (int i = 0; i < 6; i++)
0280             payload.push_back(payload_p2[i]);
0281         }
0282 
0283         //in format Block(id,payload)
0284         blocks.push_back(Block(block_id, payload));
0285 
0286         if (link % 2 != 0) {
0287           moreBXeta = false;
0288         }
0289 
0290       }  //link_itr
0291 
0292       return blocks;
0293     }
0294 
0295     uint32_t BMTFPackerInputs::wordPhMaker(const L1MuDTChambPhDigi& phInput) {
0296       uint32_t temp(0);
0297 
0298       temp = (phInput.phi() & phiMask) << phiShift | (phInput.phiB() & phiBMask) << phiBShift |
0299              (phInput.code() & qualMask) << qualShift | (phInput.RpcBit() & rpcMask) << rpcShift | (0) << 29 |
0300              (phInput.BxCnt() & bxCntMask) << bxCntShift;
0301 
0302       //    std::cout<<"uint32_t temp is: "<<std::bitset<32>(temp).to_string()<<"---- phi="<<phInput.phi()<<", phiB()="<<phInput.phiB()<<", code(qual?)="<<phInput.code()<<", RPC="<<phInput.RpcBit()<<", BC="<<phInput.BxCnt()<<std::endl;
0303       return temp;
0304     }
0305 
0306     uint32_t BMTFPackerInputs::wordThMaker(const L1MuDTChambThDigi& thInput, const bool& qualFlag) {
0307       uint32_t temp(0);
0308       if (!qualFlag) {
0309         for (int i = 6; i >= 0; i--) {
0310           temp = temp << 1;
0311           temp = temp | (thInput.position(i) & 0x1);
0312         }
0313       } else {
0314         for (int i = 6; i >= 0; i--) {
0315           temp = temp << 1;
0316           temp = temp | (thInput.quality(i) & 0x1);
0317         }
0318       }
0319 
0320       return temp;
0321     }
0322 
0323   }  // namespace stage2
0324 }  // namespace l1t
0325 DEFINE_L1T_PACKER(l1t::stage2::BMTFPackerInputs);