CMS 3D CMS Logo

IntermediateMuonUnpacker.cc
Go to the documentation of this file.
4 
6 
7 #include "GMTCollections.h"
9 
10 namespace l1t {
11  namespace stage2 {
12  bool
14  {
15  LogDebug("L1T") << "Block ID = " << block.header().getID() << " size = " << block.header().getSize();
16 
17  auto payload = block.payload();
18 
19  const unsigned int nWords = 6; // every link transmits 6 words (3 muons) per bx
20  int nBX, firstBX, lastBX;
21  nBX = int(ceil(block.header().getSize() / nWords));
22  getBXRange(nBX, firstBX, lastBX);
23 
24  // decide which collections to use according to the link ID
25  unsigned int linkId = (block.header().getID() - 1) / 2;
26  unsigned int coll1Cnt = 0;
27  MuonBxCollection* res1;
28  MuonBxCollection* res2;
29  // Intermediate muons come on uGMT output links 24-31.
30  // Each link can transmit 3 muons and we receive 4 intermediate muons from
31  // EMTF/OMTF on each detector side and 8 intermediate muons from BMTF.
32  // Therefore, the muon at a certain position on a link has to be filled
33  // in a specific collection. The order is from links 24-31:
34  // 4 muons from EMTF pos, 4 from OMTF pos, 8 from BMTF, 4 from OMTF neg,
35  // and 4 from EMTF neg.
36  switch (linkId) {
37  case 24:
38  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFPos();
39  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFPos();
40  coll1Cnt = 3;
41  break;
42  case 25:
43  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFPos();
44  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFPos();
45  coll1Cnt = 1;
46  break;
47  case 26:
48  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFPos();
49  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
50  coll1Cnt = 2;
51  break;
52  case 27:
53  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
54  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
55  coll1Cnt = 3;
56  break;
57  case 28:
58  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
59  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
60  coll1Cnt = 3;
61  break;
62  case 29:
63  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsBMTF();
64  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFNeg();
65  coll1Cnt = 1;
66  break;
67  case 30:
68  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsOMTFNeg();
69  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFNeg();
70  coll1Cnt = 2;
71  break;
72  case 31:
73  res1 = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFNeg();
74  res2 = static_cast<GMTCollections*>(coll)->getImdMuonsEMTFNeg();
75  coll1Cnt = 3;
76  break;
77  default:
78  edm::LogWarning("L1T") << "Block ID " << block.header().getID() << " not associated with intermediate muons. Skip.";
79  return false;
80  }
81  res1->setBXRange(firstBX, lastBX);
82  res2->setBXRange(firstBX, lastBX);
83 
84  LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX;
85 
86  // Initialise indices
87  unsigned int i = 0;
88  unsigned int muonCnt = 0;
89 
90  // Loop over multiple BX and then number of muons filling muon collection
91  for (int bx = firstBX; bx <= lastBX; ++bx) {
92  for (unsigned nWord = 0; nWord < nWords && i < block.header().getSize(); nWord += 2, ++muonCnt) {
93  uint32_t raw_data_00_31 = payload[i++];
94  uint32_t raw_data_32_63 = payload[i++];
95  LogDebug("L1T") << "raw_data_00_31 = 0x" << hex << raw_data_00_31 << " raw_data_32_63 = 0x" << raw_data_32_63;
96  // skip empty muons (hwPt == 0)
98  LogDebug("L1T") << "Muon hwPt zero. Skip.";
99  continue;
100  }
101 
102  Muon mu;
103 
104  // The intermediate muons do not have coordinates estimated at the vertex in the RAW data
105  // Setting FW version to 0 makes the unpacker use the 2016 RAW format
106  MuonRawDigiTranslator::fillMuon(mu, raw_data_00_31, raw_data_32_63, 1402, 0);
107 
108  LogDebug("L1T") << "Mu" << nWord/2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT " << mu.hwPt() << " iso " << mu.hwIso() << " qual " << mu.hwQual() << " charge " << mu.hwCharge() << " charge valid " << mu.hwChargeValid();
109 
110  if (muonCnt < coll1Cnt) {
111  res1->push_back(bx, mu);
112  } else {
113  res2->push_back(bx, mu);
114  }
115  }
116  }
117  return true;
118  }
119  }
120 }
121 
#define LogDebug(id)
unsigned int getID() const
Definition: Block.h:22
void getBXRange(int nbx, int &first, int &last)
BlockHeader header() const
Definition: Block.h:60
int hwPhi() const
Definition: L1Candidate.h:50
delete x;
Definition: CaloConfig.h:22
std::vector< uint32_t > payload() const
Definition: Block.h:61
int hwIso() const
Definition: L1Candidate.h:52
payload
payload postfix for testing
Definition: Muon.py:1
virtual bool unpack(const Block &block, UnpackerCollections *coll) override
const int mu
Definition: Constants.h:22
int hwEta() const
Definition: L1Candidate.h:49
int hwQual() const
Definition: L1Candidate.h:51
JetCorrectorParametersCollection coll
Definition: classes.h:10
int hwPt() const
Definition: L1Candidate.h:48
static const unsigned ptShift_
void setBXRange(int bxFirst, int bxLast)
#define DEFINE_L1T_UNPACKER(type)
unsigned int getSize() const
Definition: Block.h:23
int hwChargeValid() const
Definition: Muon.h:83
void push_back(int bx, T object)
int hwCharge() const
Definition: Muon.h:82
static const unsigned ptMask_
static void fillMuon(Muon &, uint32_t, uint32_t, int, unsigned int)