CMS 3D CMS Logo

EMTFBlockRPC.cc
Go to the documentation of this file.
1 // Code to unpack the "RPC Data Record"
2 
4 
5 #include "EMTFCollections.h"
6 #include "EMTFUnpackerTools.h"
7 
8 // This is the "header" - no EMTFBlockRPC.h file is needed
9 namespace l1t {
10  namespace stage2 {
11  namespace emtf {
12 
13  class RPCBlockUnpacker : public Unpacker { // "RPCBlockUnpacker" inherits from "Unpacker"
14  public:
15  virtual int checkFormat(const Block& block);
16  // virtual bool checkFormat() override; // Return "false" if block format does not match expected format
17  bool unpack(const Block& block,
18  UnpackerCollections* coll) override; // Apparently it's always good to use override in C++
19  // virtual bool packBlock(const Block& block, UnpackerCollections *coll) override;
20  };
21 
22  // class RPCBlockPacker : public Packer { // "RPCBlockPacker" inherits from "Packer"
23  // public:
24  // virtual bool unpack(const Block& block, UnpackerCollections *coll) override; // Apparently it's always good to use override in C++
25  // };
26 
27  } // namespace emtf
28  } // namespace stage2
29 } // namespace l1t
30 
31 namespace l1t {
32  namespace stage2 {
33  namespace emtf {
34 
36  auto payload = block.payload();
37  int errors = 0;
38 
39  // Check the number of 16-bit words
40  if (payload.size() != 4) {
41  errors += 1;
42  edm::LogError("L1T|EMTF") << "Payload size in 'RPC Data Record' is different than expected";
43  }
44 
45  // Check that each word is 16 bits
46  for (unsigned int i = 0; i < 4; i++) {
47  if (GetHexBits(payload[i], 16, 31) != 0) {
48  errors += 1;
49  edm::LogError("L1T|EMTF") << "Payload[" << i << "] has more than 16 bits in 'RPC Data Record'";
50  }
51  }
52 
53  uint16_t RPCa = payload[0];
54  uint16_t RPCb = payload[1];
55  uint16_t RPCc = payload[2];
56  uint16_t RPCd = payload[3];
57 
58  // Check Format
59  if (GetHexBits(RPCa, 15, 15) != 0) {
60  errors += 1;
61  edm::LogError("L1T|EMTF") << "Format identifier bits in RPCa are incorrect";
62  }
63  if (GetHexBits(RPCb, 15, 15) != 0) {
64  errors += 1;
65  edm::LogError("L1T|EMTF") << "Format identifier bits in RPCb are incorrect";
66  }
67  if (GetHexBits(RPCc, 15, 15) != 1) {
68  errors += 1;
69  edm::LogError("L1T|EMTF") << "Format identifier bits in RPCc are incorrect";
70  }
71  if (GetHexBits(RPCd, 15, 15) != 0) {
72  errors += 1;
73  edm::LogError("L1T|EMTF") << "Format identifier bits in RPCd are incorrect";
74  }
75 
76  return errors;
77  }
78 
79  // Converts station, ring, sector, subsector, neighbor, and segment from the RPC output
81  int& ring,
82  int& sector,
83  int& subsector,
84  int& neighbor,
85  int& segment,
86  const int evt_sector,
87  const int frame,
88  const int word,
89  const int link) {
90  station = -99;
91  ring = -99;
92  sector = -99;
93  subsector = -99;
94  neighbor = -99;
95  segment = -99;
96 
97  // "link" is the "link index" field (0 - 6) in the EMTF DAQ document, not "link number" (1 - 7)
98  // Neighbor indicated by link == 0
99  sector = (link != 0 ? evt_sector : (evt_sector == 1 ? 6 : evt_sector - 1));
100  subsector = (link != 0 ? link : 6);
101  neighbor = (link == 0 ? 1 : 0);
102  segment = (word % 2);
103 
104  if (frame == 0) {
105  station = (word < 2 ? 1 : 2);
106  ring = 2;
107  } else if (frame == 1) {
108  station = 3;
109  ring = (word < 2 ? 2 : 3);
110  } else if (frame == 2) {
111  station = 4;
112  ring = (word < 2 ? 2 : 3);
113  }
114  } // End function: void convert_RPC_location()
115 
117  // std::cout << "Inside EMTFBlockRPC.cc: unpack" << std::endl;
118 
119  // Get the payload for this block, made up of 16-bit words (0xffff)
120  // Format defined in MTF7Payload::getBlock() in src/Block.cc
121  // payload[0] = bits 0-15, payload[1] = 16-31, payload[3] = 32-47, etc.
122  auto payload = block.payload();
123 
124  // Run 3 has a different EMTF DAQ output format since August 26th
125  // Computed as (Year - 2000)*2^9 + Month*2^5 + Day (see Block.cc and EMTFBlockTrailers.cc)
126  bool run3_DAQ_format =
127  (getAlgoVersion() >=
128  11546); // Firmware from 26.08.22 which enabled new Run 3 DAQ format for RPCs - EY 13.09.22
129  bool reducedDAQWindow =
130  (getAlgoVersion() >=
131  11656); // Firmware from 08.12.22 which is used as a flag for new reduced readout window - EY 01.03.23
132 
133  int nTPs = run3_DAQ_format ? 2 : 1;
134 
135  // Check Format of Payload
136  l1t::emtf::RPC RPC_;
137  for (int err = 0; err < checkFormat(block); err++)
138  RPC_.add_format_error();
139 
140  // Assign payload to 16-bit words
141  uint16_t RPCa = payload[0];
142  uint16_t RPCb = payload[1];
143  uint16_t RPCc = payload[2];
144  uint16_t RPCd = payload[3];
145 
146  // If there are 2 TPs in the block we fill them 1 by 1
147  for (int i = 1; i <= nTPs; i++) {
148  // res is a pointer to a collection of EMTFDaqOut class objects
149  // There is one EMTFDaqOut for each MTF7 (60 deg. sector) in the event
151  res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
152  int iOut = res->size() - 1;
153 
154  EMTFHitCollection* res_hit;
155  res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
156  EMTFHit Hit_;
157 
158  CPPFDigiCollection* res_CPPF;
159  res_CPPF = static_cast<EMTFCollections*>(coll)->getEMTFCPPFs();
160 
162  // Unpack the RPC Data Record
164 
165  if (run3_DAQ_format) { // Run 3 DAQ format has 2 TPs per block
166  if (i == 1) {
167  RPC_.set_phi(GetHexBits(RPCa, 0, 10));
168  RPC_.set_word(GetHexBits(RPCa, 11, 12));
169  RPC_.set_frame(GetHexBits(RPCa, 13, 14));
170 
171  if (reducedDAQWindow) // reduced DAQ window is used only after run3 DAQ format
172  RPC_.set_tbin(GetHexBits(RPCb, 0, 2) + 1);
173  else
174  RPC_.set_tbin(GetHexBits(RPCb, 0, 2));
175  RPC_.set_vp(GetHexBits(RPCb, 3, 3));
176  RPC_.set_theta(GetHexBits(RPCb, 4, 8));
177  RPC_.set_bc0(GetHexBits(RPCb, 9, 9));
178  RPC_.set_link(GetHexBits(RPCb, 12, 14)); // Link index (0 - 6); link number runs 1 - 7
179  } else if (i == 2) {
180  RPC_.set_phi(GetHexBits(RPCc, 0, 10));
181  RPC_.set_word(GetHexBits(RPCc, 11, 12));
182  RPC_.set_frame(GetHexBits(RPCc, 13, 14));
183 
184  if (reducedDAQWindow) // reduced DAQ window is used only after run3 DAQ format
185  RPC_.set_tbin(GetHexBits(RPCd, 0, 2) + 1);
186  else
187  RPC_.set_tbin(GetHexBits(RPCd, 0, 2));
188  RPC_.set_vp(GetHexBits(RPCd, 3, 3));
189  RPC_.set_theta(GetHexBits(RPCd, 4, 8));
190  RPC_.set_bc0(GetHexBits(RPCd, 9, 9));
191  RPC_.set_link(GetHexBits(RPCd, 12, 14)); // Link index (0 - 6); link number runs 1 - 7
192  }
193  } else { // Run 2 DAQ format
194  RPC_.set_phi(GetHexBits(RPCa, 0, 10));
195 
196  RPC_.set_theta(GetHexBits(RPCb, 0, 4));
197  RPC_.set_word(GetHexBits(RPCb, 8, 9));
198  RPC_.set_frame(GetHexBits(RPCb, 10, 11));
199  RPC_.set_link(GetHexBits(RPCb, 12, 14)); // Link index (0 - 6); link number runs 1 - 7
200 
201  RPC_.set_rpc_bxn(GetHexBits(RPCc, 0, 11));
202  RPC_.set_bc0(GetHexBits(RPCc, 14, 14));
203 
204  RPC_.set_tbin(GetHexBits(RPCd, 0, 2));
205  RPC_.set_vp(GetHexBits(RPCd, 3, 3));
206 
207  // RPC_.set_dataword ( uint64_t dataword);
208  }
209 
210  // Convert specially-encoded RPC quantities
211  int _station, _ring, _sector, _subsector, _neighbor, _segment;
212  convert_RPC_location(_station,
213  _ring,
214  _sector,
215  _subsector,
216  _neighbor,
217  _segment,
218  (res->at(iOut)).PtrEventHeader()->Sector(),
219  RPC_.Frame(),
220  RPC_.Word(),
221  RPC_.Link());
222 
223  // Rotate by 20 deg to match RPC convention in CMSSW
224  int _sector_rpc = (_subsector < 5) ? _sector : (_sector % 6) + 1;
225  // Rotate by 2 to match RPC convention in CMSSW (RPCDetId.h)
226  int _subsector_rpc = ((_subsector + 1) % 6) + 1;
227  // Define chamber number
228  int _chamber = (_sector_rpc - 1) * 6 + _subsector_rpc;
229  // Define CSC-like subsector
230  int _subsector_csc = (_station != 1) ? 0 : ((_chamber % 6 > 2) ? 1 : 2);
231 
232  Hit_.set_station(_station);
233  Hit_.set_ring(_ring);
234  Hit_.set_sector(_sector);
235  Hit_.set_subsector(_subsector_csc);
236  Hit_.set_sector_RPC(_sector_rpc);
237  Hit_.set_subsector_RPC(_subsector_rpc);
238  Hit_.set_chamber(_chamber);
239  Hit_.set_neighbor(_neighbor);
240  Hit_.set_pc_segment(_segment);
241  Hit_.set_fs_segment(_segment);
242  Hit_.set_bt_segment(_segment);
243 
244  // Fill the EMTFHit
245  ImportRPC(Hit_, RPC_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());
246 
247  // Set the stub number for this hit
248  // Each chamber can send up to 2 stubs per BX
249  // Also count stubs in corresponding CSC chamber; RPC hit counting is on top of LCT counting
250  Hit_.set_stub_num(0);
251  // See if matching hit is already in event record
252  bool exact_duplicate = false;
253  for (auto const& iHit : *res_hit) {
254  if (Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() && Hit_.Station() == iHit.Station() &&
255  Hit_.Chamber() == iHit.Chamber()) {
256  if ((iHit.Is_CSC() == 1 && iHit.Ring() == 2) ||
257  (iHit.Is_RPC() == 1)) { // RPC rings 2 and 3 both map to CSC ring 2
258  if (Hit_.Neighbor() == iHit.Neighbor()) {
259  Hit_.set_stub_num(Hit_.Stub_num() + 1);
260  if (iHit.Is_RPC() == 1 && iHit.Ring() == Hit_.Ring() && iHit.Theta_fp() == Hit_.Theta_fp() &&
261  iHit.Phi_fp() == Hit_.Phi_fp()) {
262  exact_duplicate = true;
263  }
264  }
265  }
266  }
267  } // End loop: for (auto const & iHit : *res_hit)
268 
269  // Reject TPs with out-of-range BX values. This needs to be adjusted if we increase l1a_window parameter in EMTF config - EY 03.08.2022
270  if (Hit_.BX() > 3 or Hit_.BX() < -3) {
271  edm::LogWarning("L1T|EMTF") << "EMTF unpacked CPPF digis with out-of-range BX! BX " << Hit_.BX()
272  << ", endcap " << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector "
273  << Hit_.Sector() << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring()
274  << ", chamber " << Hit_.Chamber() << ", theta " << Hit_.Theta_fp() / 4
275  << ", phi " << Hit_.Phi_fp() / 4 << std::endl;
276  return true;
277  }
278 
279  if (exact_duplicate)
280  edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate CPPF digis: BX " << Hit_.BX() << ", endcap "
281  << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector "
282  << Hit_.Sector() << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring()
283  << ", chamber " << Hit_.Chamber() << ", theta " << Hit_.Theta_fp() / 4
284  << ", phi " << Hit_.Phi_fp() / 4 << std::endl;
285 
286  (res->at(iOut)).push_RPC(RPC_);
287  if (!exact_duplicate and Hit_.Valid())
288  res_hit->push_back(Hit_);
289  if (!exact_duplicate and Hit_.Valid())
290  res_CPPF->push_back(Hit_.CreateCPPFDigi());
291  }
292 
293  // Finished with unpacking one RPC Data Record
294  return true;
295 
296  } // End bool RPCBlockUnpacker::unpack
297 
298  // bool RPCBlockPacker::pack(const Block& block, UnpackerCollections *coll) {
299  // std::cout << "Inside RPCBlockPacker::pack" << std::endl;
300  // return true;
301  // } // End bool RPCBlockPacker::pack
302 
303  } // End namespace emtf
304  } // End namespace stage2
305 } // End namespace l1t
306 
308 // DEFINE_L1T_PACKER(l1t::stage2::RPCBlockPacker);
void set_subsector_RPC(int bits)
Definition: EMTFHit.h:142
void set_neighbor(int bits)
Definition: EMTFHit.h:147
int Link() const
Definition: RPC.h:46
unsigned int getAlgoVersion()
Definition: Unpacker.h:18
void set_stub_num(int bits)
Definition: EMTFHit.h:180
void set_station(int bits)
Definition: EMTFHit.h:136
void convert_RPC_location(int &station, int &ring, int &sector, int &subsector, int &neighbor, int &segment, const int evt_sector, const int frame, const int word, const int link)
Definition: EMTFBlockRPC.cc:80
void add_format_error()
Definition: RPC.h:39
int Neighbor() const
Definition: EMTFHit.h:215
int Word() const
Definition: RPC.h:44
int Phi_fp() const
Definition: EMTFHit.h:264
Definition: Event.h:15
delete x;
Definition: CaloConfig.h:22
int Valid() const
Definition: EMTFHit.h:235
bool unpack(const Block &block, UnpackerCollections *coll) override
Log< level::Error, false > LogError
void set_word(int bits)
Definition: RPC.h:32
Definition: Electron.h:6
void set_ring(int bits)
Definition: EMTFHit.h:137
void ImportRPC(EMTFHit &_hit, const l1t::emtf::RPC _RPC, const int _endcap, const int _evt_sector)
void set_frame(int bits)
Definition: RPC.h:33
uint64_t word
void set_theta(int bits)
Definition: RPC.h:31
CPPFDigi CreateCPPFDigi() const
Definition: EMTFHit.cc:50
void set_bt_segment(int bits)
Definition: EMTFHit.h:188
void set_tbin(int bits)
Definition: RPC.h:37
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
std::vector< EMTFHit > EMTFHitCollection
Definition: EMTFHit.h:366
std::vector< EMTFDaqOut > EMTFDaqOutCollection
Definition: EMTFDaqOut.h:179
int BX() const
Definition: EMTFHit.h:262
void set_bc0(int bits)
Definition: RPC.h:36
int Theta_fp() const
Definition: EMTFHit.h:265
void set_pc_segment(int bits)
Definition: EMTFHit.h:152
void set_fs_segment(int bits)
Definition: EMTFHit.h:185
int Frame() const
Definition: RPC.h:45
void set_sector_RPC(int bits)
Definition: EMTFHit.h:139
void set_sector(int bits)
Definition: EMTFHit.h:138
int Endcap() const
Definition: EMTFHit.h:203
int Station() const
Definition: EMTFHit.h:204
int Stub_num() const
Definition: EMTFHit.h:263
int Chamber() const
Definition: EMTFHit.h:211
void set_phi(int bits)
Definition: RPC.h:30
void set_link(int bits)
Definition: RPC.h:34
#define DEFINE_L1T_UNPACKER(type)
void set_rpc_bxn(int bits)
Definition: RPC.h:35
int Ring() const
Definition: EMTFHit.h:205
Definition: errors.py:1
uint16_t GetHexBits(uint16_t word, uint16_t lowBit, uint16_t highBit)
Log< level::Warning, false > LogWarning
void set_vp(int bits)
Definition: RPC.h:38
void set_chamber(int bits)
Definition: EMTFHit.h:143
virtual int checkFormat(const Block &block)
Definition: EMTFBlockRPC.cc:35
void set_subsector(int bits)
Definition: EMTFHit.h:141
std::vector< CPPFDigi > CPPFDigiCollection
Definition: CPPFDigi.h:83
int Sector() const
Definition: EMTFHit.h:206