CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  // Check Format of Payload
125  l1t::emtf::RPC RPC_;
126  for (int err = 0; err < checkFormat(block); err++)
127  RPC_.add_format_error();
128 
129  // Assign payload to 16-bit words
130  uint16_t RPCa = payload[0];
131  uint16_t RPCb = payload[1];
132  uint16_t RPCc = payload[2];
133  uint16_t RPCd = payload[3];
134 
135  // res is a pointer to a collection of EMTFDaqOut class objects
136  // There is one EMTFDaqOut for each MTF7 (60 deg. sector) in the event
138  res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
139  int iOut = res->size() - 1;
140 
141  EMTFHitCollection* res_hit;
142  res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
143  EMTFHit Hit_;
144 
145  CPPFDigiCollection* res_CPPF;
146  res_CPPF = static_cast<EMTFCollections*>(coll)->getEMTFCPPFs();
147 
149  // Unpack the RPC Data Record
151 
152  RPC_.set_phi(GetHexBits(RPCa, 0, 10));
153 
154  RPC_.set_theta(GetHexBits(RPCb, 0, 4));
155  RPC_.set_word(GetHexBits(RPCb, 8, 9));
156  RPC_.set_frame(GetHexBits(RPCb, 10, 11));
157  RPC_.set_link(GetHexBits(RPCb, 12, 14)); // Link index (0 - 6); link number runs 1 - 7
158 
159  RPC_.set_rpc_bxn(GetHexBits(RPCc, 0, 11));
160  RPC_.set_bc0(GetHexBits(RPCc, 14, 14));
161 
162  RPC_.set_tbin(GetHexBits(RPCd, 0, 2));
163  RPC_.set_vp(GetHexBits(RPCd, 3, 3));
164 
165  // RPC_.set_dataword ( uint64_t dataword);
166 
167  // Convert specially-encoded RPC quantities
168  int _station, _ring, _sector, _subsector, _neighbor, _segment;
169  convert_RPC_location(_station,
170  _ring,
171  _sector,
172  _subsector,
173  _neighbor,
174  _segment,
175  (res->at(iOut)).PtrEventHeader()->Sector(),
176  RPC_.Frame(),
177  RPC_.Word(),
178  RPC_.Link());
179 
180  // Rotate by 20 deg to match RPC convention in CMSSW
181  int _sector_rpc = (_subsector < 5) ? _sector : (_sector % 6) + 1;
182  // Rotate by 2 to match RPC convention in CMSSW (RPCDetId.h)
183  int _subsector_rpc = ((_subsector + 1) % 6) + 1;
184  // Define chamber number
185  int _chamber = (_sector_rpc - 1) * 6 + _subsector_rpc;
186  // Define CSC-like subsector
187  int _subsector_csc = (_station != 1) ? 0 : ((_chamber % 6 > 2) ? 1 : 2);
188 
189  Hit_.set_station(_station);
190  Hit_.set_ring(_ring);
191  Hit_.set_sector(_sector);
192  Hit_.set_subsector(_subsector_csc);
193  Hit_.set_sector_RPC(_sector_rpc);
194  Hit_.set_subsector_RPC(_subsector_rpc);
195  Hit_.set_chamber(_chamber);
196  Hit_.set_neighbor(_neighbor);
197  Hit_.set_pc_segment(_segment);
198  Hit_.set_fs_segment(_segment);
199  Hit_.set_bt_segment(_segment);
200 
201  // Fill the EMTFHit
202  ImportRPC(Hit_, RPC_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());
203 
204  // Set the stub number for this hit
205  // Each chamber can send up to 2 stubs per BX
206  // Also count stubs in corresponding CSC chamber; RPC hit counting is on top of LCT counting
207  Hit_.set_stub_num(0);
208  // See if matching hit is already in event record
209  bool exact_duplicate = false;
210  for (auto const& iHit : *res_hit) {
211  if (Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() && Hit_.Station() == iHit.Station() &&
212  Hit_.Chamber() == iHit.Chamber()) {
213  if ((iHit.Is_CSC() == 1 && iHit.Ring() == 2) ||
214  (iHit.Is_RPC() == 1)) { // RPC rings 2 and 3 both map to CSC ring 2
215  if (Hit_.Neighbor() == iHit.Neighbor()) {
216  Hit_.set_stub_num(Hit_.Stub_num() + 1);
217  if (iHit.Is_RPC() == 1 && iHit.Ring() == Hit_.Ring() && iHit.Theta_fp() == Hit_.Theta_fp() &&
218  iHit.Phi_fp() == Hit_.Phi_fp()) {
219  exact_duplicate = true;
220  }
221  }
222  }
223  }
224  } // End loop: for (auto const & iHit : *res_hit)
225 
226  if (exact_duplicate)
227  edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate CPPF digis: BX " << Hit_.BX() << ", endcap "
228  << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector " << Hit_.Sector()
229  << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
230  << Hit_.Chamber() << ", theta " << Hit_.Theta_fp() / 4 << ", phi "
231  << Hit_.Phi_fp() / 4 << std::endl;
232 
233  (res->at(iOut)).push_RPC(RPC_);
234  if (!exact_duplicate)
235  res_hit->push_back(Hit_);
236  if (!exact_duplicate)
237  res_CPPF->push_back(Hit_.CreateCPPFDigi());
238 
239  // Finished with unpacking one RPC Data Record
240  return true;
241 
242  } // End bool RPCBlockUnpacker::unpack
243 
244  // bool RPCBlockPacker::pack(const Block& block, UnpackerCollections *coll) {
245  // std::cout << "Inside RPCBlockPacker::pack" << std::endl;
246  // return true;
247  // } // End bool RPCBlockPacker::pack
248 
249  } // End namespace emtf
250  } // End namespace stage2
251 } // End namespace l1t
252 
254 // 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
const std::vector< uint32_t > & payload() const
Definition: Block.h:86
void set_stub_num(int bits)
Definition: EMTFHit.h:180
int Phi_fp() const
Definition: EMTFHit.h:264
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
bool unpack(const Block &block, UnpackerCollections *coll) override
Log< level::Error, false > LogError
void set_word(int bits)
Definition: RPC.h:32
void set_ring(int bits)
Definition: EMTFHit.h:137
int Chamber() const
Definition: EMTFHit.h:211
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
int Sector() const
Definition: EMTFHit.h:206
uint64_t word
void set_theta(int bits)
Definition: RPC.h:31
void set_bt_segment(int bits)
Definition: EMTFHit.h:188
void set_tbin(int bits)
Definition: RPC.h:37
int BX() const
Definition: EMTFHit.h:262
CPPFDigi CreateCPPFDigi() const
Definition: EMTFHit.cc:50
int Word() const
Definition: RPC.h:44
std::vector< EMTFHit > EMTFHitCollection
Definition: EMTFHit.h:366
std::vector< EMTFDaqOut > EMTFDaqOutCollection
Definition: EMTFDaqOut.h:179
void set_bc0(int bits)
Definition: RPC.h:36
int Ring() const
Definition: EMTFHit.h:205
void set_pc_segment(int bits)
Definition: EMTFHit.h:152
int Frame() const
Definition: RPC.h:45
void set_fs_segment(int bits)
Definition: EMTFHit.h:185
void set_sector_RPC(int bits)
Definition: EMTFHit.h:139
void set_sector(int bits)
Definition: EMTFHit.h:138
int Station() const
Definition: EMTFHit.h:204
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 Endcap() const
Definition: EMTFHit.h:203
int Stub_num() const
Definition: EMTFHit.h:263
uint16_t GetHexBits(uint16_t word, uint16_t lowBit, uint16_t highBit)
Log< level::Warning, false > LogWarning
int Theta_fp() const
Definition: EMTFHit.h:265
void set_vp(int bits)
Definition: RPC.h:38
int Link() const
Definition: RPC.h:46
void set_chamber(int bits)
Definition: EMTFHit.h:143
int Neighbor() const
Definition: EMTFHit.h:215
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