CMS 3D CMS Logo

EMTFBlockME.cc
Go to the documentation of this file.
1 // Code to unpack the "ME Data Record"
2 
4 
5 #include "EMTFCollections.h"
6 #include "EMTFUnpackerTools.h"
7 
8 // This is the "header" - no EMTFBlockME.h file is needed
9 namespace l1t {
10  namespace stage2 {
11  namespace emtf {
12 
13  class MEBlockUnpacker : public Unpacker { // "MEBlockUnpacker" inherits from "Unpacker"
14  public:
15  virtual int checkFormat(const Block& block);
16  bool unpack(const Block& block,
17  UnpackerCollections* coll) override; // Apparently it's always good to use override in C++
18  // virtual bool packBlock(const Block& block, UnpackerCollections *coll) override;
19  };
20 
21  // class MEBlockPacker : public Packer { // "MEBlockPacker" inherits from "Packer"
22  // public:
23  // virtual bool unpack(const Block& block, UnpackerCollections *coll) override; // Apparently it's always good to use override in C++
24  // };
25 
26  } // namespace emtf
27  } // namespace stage2
28 } // namespace l1t
29 
30 namespace l1t {
31  namespace stage2 {
32  namespace emtf {
33 
35  auto payload = block.payload();
36  int errors = 0;
37 
38  // Check the number of 16-bit words
39  if (payload.size() != 4) {
40  errors += 1;
41  edm::LogError("L1T|EMTF") << "Payload size in 'ME Data Record' is different than expected";
42  }
43 
44  // Check that each word is 16 bits
45  for (unsigned int i = 0; i < 4; i++) {
46  if (GetHexBits(payload[i], 16, 31) != 0) {
47  errors += 1;
48  edm::LogError("L1T|EMTF") << "Payload[" << i << "] has more than 16 bits in 'ME Data Record'";
49  }
50  }
51 
52  uint16_t MEa = payload[0];
53  uint16_t MEb = payload[1];
54  uint16_t MEc = payload[2];
55  uint16_t MEd = payload[3];
56 
57  //Check Format
58  if (GetHexBits(MEa, 15, 15) != 1) {
59  errors += 1;
60  edm::LogError("L1T|EMTF") << "Format identifier bits in MEa are incorrect";
61  }
62  if (GetHexBits(MEb, 15, 15) != 1) {
63  errors += 1;
64  edm::LogError("L1T|EMTF") << "Format identifier bits in MEb are incorrect";
65  }
66  if (GetHexBits(MEc, 15, 15) != 0) {
67  errors += 1;
68  edm::LogError("L1T|EMTF") << "Format identifier bits in MEc are incorrect";
69  }
70  if (GetHexBits(MEd, 15, 15) != 0) {
71  errors += 1;
72  edm::LogError("L1T|EMTF") << "Format identifier bits in MEd are incorrect";
73  }
74 
75  return errors;
76  }
77 
78  // Converts station, CSC_ID, sector, subsector, and neighbor from the ME output
79  std::vector<int> convert_ME_location(int _station, int _csc_ID, int _sector, bool _csc_ID_shift = false) {
80  int new_sector = _sector;
81  int new_csc_ID = _csc_ID;
82  if (_csc_ID_shift)
83  new_csc_ID += 1; // Before FW update on 05.05.16, shift by +1 from 0,1,2... convention to 1,2,3...
84  if (_station == 0) {
85  int arr[] = {1, new_csc_ID, new_sector, 1, 0};
86  std::vector<int> vec(arr, arr + 5);
87  return vec;
88  } else if (_station == 1) {
89  int arr[] = {1, new_csc_ID, new_sector, 2, 0};
90  std::vector<int> vec(arr, arr + 5);
91  return vec;
92  } else if (_station <= 4) {
93  int arr[] = {_station, new_csc_ID, new_sector, -1, 0};
94  std::vector<int> vec(arr, arr + 5);
95  return vec;
96  } else if (_station == 5) {
97  new_sector = (_sector != 1) ? _sector - 1 : 6; // Indicates neighbor chamber, don't return yet
98  } else {
99  int arr[] = {_station, _csc_ID, _sector, -99, -99};
100  std::vector<int> vec(arr, arr + 5);
101  return vec;
102  }
103 
104  // Mapping for chambers from neighboring sector
105  if (new_csc_ID == 1) {
106  int arr[] = {1, 3, new_sector, 2, 1};
107  std::vector<int> vec(arr, arr + 5);
108  return vec;
109  } else if (new_csc_ID == 2) {
110  int arr[] = {1, 6, new_sector, 2, 1};
111  std::vector<int> vec(arr, arr + 5);
112  return vec;
113  } else if (new_csc_ID == 3) {
114  int arr[] = {1, 9, new_sector, 2, 1};
115  std::vector<int> vec(arr, arr + 5);
116  return vec;
117  } else if (new_csc_ID == 4) {
118  int arr[] = {2, 3, new_sector, -1, 1};
119  std::vector<int> vec(arr, arr + 5);
120  return vec;
121  } else if (new_csc_ID == 5) {
122  int arr[] = {2, 9, new_sector, -1, 1};
123  std::vector<int> vec(arr, arr + 5);
124  return vec;
125  } else if (new_csc_ID == 6) {
126  int arr[] = {3, 3, new_sector, -1, 1};
127  std::vector<int> vec(arr, arr + 5);
128  return vec;
129  } else if (new_csc_ID == 7) {
130  int arr[] = {3, 9, new_sector, -1, 1};
131  std::vector<int> vec(arr, arr + 5);
132  return vec;
133  } else if (new_csc_ID == 8) {
134  int arr[] = {4, 3, new_sector, -1, 1};
135  std::vector<int> vec(arr, arr + 5);
136  return vec;
137  } else if (new_csc_ID == 9) {
138  int arr[] = {4, 9, new_sector, -1, 1};
139  std::vector<int> vec(arr, arr + 5);
140  return vec;
141  } else {
142  int arr[] = {_station, _csc_ID, _sector, -99, -99};
143  std::vector<int> vec(arr, arr + 5);
144  return vec;
145  }
146  }
147 
149  // std::cout << "Inside EMTFBlockME.cc: unpack" << std::endl;
150 
151  // Get the payload for this block, made up of 16-bit words (0xffff)
152  // Format defined in MTF7Payload::getBlock() in src/Block.cc
153  // payload[0] = bits 0-15, payload[1] = 16-31, payload[3] = 32-47, etc.
154  auto payload = block.payload();
155 
156  // Assign payload to 16-bit words
157  uint16_t MEa = payload[0];
158  uint16_t MEb = payload[1];
159  uint16_t MEc = payload[2];
160  uint16_t MEd = payload[3];
161 
162  // Check Format of Payload
163  l1t::emtf::ME ME_;
164  for (int err = 0; err < checkFormat(block); err++)
165  ME_.add_format_error();
166 
167  // res is a pointer to a collection of EMTFDaqOut class objects
168  // There is one EMTFDaqOut for each MTF7 (60 deg. sector) in the event
170  res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
171  int iOut = res->size() - 1;
172 
173  EMTFHitCollection* res_hit;
174  res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
175  EMTFHit Hit_;
176 
178  res_LCT = static_cast<EMTFCollections*>(coll)->getEMTFLCTs();
179 
180  CSCShowerDigiCollection* res_shower;
181  res_shower = static_cast<EMTFCollections*>(coll)->getEMTFCSCShowers();
182 
184  // Unpack the ME Data Record
186 
187  // Run 3 has a different EMTF DAQ output format
188  // Computed as (Year - 2000)*2^9 + Month*2^5 + Day (see Block.cc and EMTFBlockTrailers.cc)
189  bool run3_DAQ_format =
190  (getAlgoVersion() >= 11460); // Firmware from 04.06.22 which enabled new Run 3 DAQ format - EY 04.07.22
191 
192  // Set fields assuming Run 2 format. Modify for Run 3 later
193  ME_.set_clct_pattern(GetHexBits(MEa, 0, 3));
194  ME_.set_quality(GetHexBits(MEa, 4, 7));
195  ME_.set_wire(GetHexBits(MEa, 8, 14));
196 
197  ME_.set_strip(GetHexBits(MEb, 0, 7));
198  ME_.set_csc_ID(GetHexBits(MEb, 8, 11));
199  ME_.set_lr(GetHexBits(MEb, 12, 12));
200  ME_.set_bxe(GetHexBits(MEb, 13, 13));
201  ME_.set_bc0(GetHexBits(MEb, 14, 14));
202 
203  ME_.set_me_bxn(GetHexBits(MEc, 0, 11));
204  ME_.set_nit(GetHexBits(MEc, 12, 12));
205  ME_.set_cik(GetHexBits(MEc, 13, 13));
206  ME_.set_afff(GetHexBits(MEc, 14, 14));
207 
208  ME_.set_tbin(GetHexBits(MEd, 0, 2));
209  ME_.set_vp(GetHexBits(MEd, 3, 3));
210  ME_.set_station(GetHexBits(MEd, 4, 6));
211  ME_.set_af(GetHexBits(MEd, 7, 7));
212  ME_.set_epc(GetHexBits(MEd, 8, 11));
213  ME_.set_sm(GetHexBits(MEd, 12, 12));
214  ME_.set_se(GetHexBits(MEd, 13, 13));
215  ME_.set_afef(GetHexBits(MEd, 14, 14));
216 
217  // ME_.set_dataword ( uint64_t dataword);
218 
219  // Convert specially-encoded ME quantities
220  bool csc_ID_shift = (getAlgoVersion() <=
221  8348); // For FW versions <= 28.04.2016, shift by +1 from 0,1,2... convention to 1,2,3...
222  // Computed as (Year - 2000)*2^9 + Month*2^5 + Day (see Block.cc and EMTFBlockTrailers.cc)
223  std::vector<int> conv_vals =
224  convert_ME_location(ME_.Station(), ME_.CSC_ID(), (res->at(iOut)).PtrEventHeader()->Sector(), csc_ID_shift);
225 
226  Hit_.set_station(conv_vals.at(0));
227  Hit_.set_csc_ID(conv_vals.at(1));
228  Hit_.set_sector(conv_vals.at(2));
229  Hit_.set_subsector(conv_vals.at(3));
230  Hit_.set_neighbor(conv_vals.at(4));
231  Hit_.set_ring(L1TMuonEndCap::calc_ring(Hit_.Station(), Hit_.CSC_ID(), ME_.Strip()));
232 
233  if (Hit_.Station() < 1 || Hit_.Station() > 4)
234  edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCT station = " << Hit_.Station()
235  << ", outside proper [1, 4] range" << std::endl;
236  if (Hit_.CSC_ID() < 1 || Hit_.CSC_ID() > 9)
237  edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCT CSC ID = " << Hit_.CSC_ID()
238  << ", outside proper [1, 9] range" << std::endl;
239  if (Hit_.Sector() < 1 || Hit_.Sector() > 6)
240  edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCT sector = " << Hit_.Sector()
241  << ", outside proper [1, 6] range" << std::endl;
242 
243  // Modifications for Run 3 format - EY 04.07.22
244  bool isOTMB = (Hit_.Ring() == 1 or
245  Hit_.Ring() == 4); // Data format is different between OTMBs (MEX/1) and TMBs (MEX/2-3)
246 
247  bool isRun3 =
248  isOTMB and run3_DAQ_format; // in Run3 DAQ format, OTMB TPs are Run 3 CSC TPs with CCLUT algorithm
249 
250  if (run3_DAQ_format) {
251  ME_.set_quality(GetHexBits(MEa, 4, 6));
252  ME_.set_quarter_strip(GetHexBits(MEa, 7, 7));
253 
254  ME_.set_frame(GetHexBits(MEc, 12, 12));
255 
256  ME_.set_eighth_strip(GetHexBits(MEd, 13, 13));
257 
258  if (isOTMB) { // Derive Run 2 pattern ID from Run 3 slope for OTMBs
259 
260  ME_.set_slope(GetHexBits(MEd, 8, 11));
261 
262  // convert Run-3 slope to Run-2 pattern for CSC TPs coming from MEX/1 chambers
263  // where the CCLUT algorithm is enabled
264  const unsigned slopeList[32] = {10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 2,
265  10, 10, 10, 9, 9, 9, 7, 7, 7, 5, 5, 5, 3, 3, 3, 3};
266 
267  // this LUT follows the same convention as in CSCPatternBank.cc
268  unsigned slope_and_sign(ME_.Slope());
269  if (ME_.LR() == 1) {
270  slope_and_sign += 16;
271  }
272  unsigned run2_converted_PID = slopeList[slope_and_sign];
273 
274  ME_.set_clct_pattern(run2_converted_PID);
275 
276  } else { // Use Run 2 pattern directly for TMBs
277  ME_.set_clct_pattern(GetHexBits(MEd, 8, 11));
278  }
279 
280  // Frame 1 has HMT related information
281  if (ME_.Frame() == 1) {
282  // Run 3 pattern is unused for now. Needs to be combined with rest of the word in Frame 0 - EY 04.07.22
283  ME_.set_run3_pattern(GetHexBits(MEa, 0, 0));
284 
285  // HMT[1] is in MEa, but HMT[0] is in MEb. These encode in time showers - EY 04.07.22
286  ME_.set_hmt_inTime(GetHexBits(MEb, 13, 13, MEa, 1, 1));
287 
288  // HMT[3:2] encodes out-of-time showers which are not used for now
289  ME_.set_hmt_outOfTime(GetHexBits(MEa, 2, 3));
290 
291  ME_.set_hmv(GetHexBits(MEd, 7, 7));
292  } else {
293  ME_.set_run3_pattern(GetHexBits(MEa, 0, 3));
294 
295  ME_.set_bxe(GetHexBits(MEb, 13, 13));
296 
297  ME_.set_af(GetHexBits(MEd, 7, 7));
298  }
299  }
300 
301  // Fill the EMTFHit
302  ImportME(Hit_, ME_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());
303 
304  // Fill the CSCShowerDigi
305  CSCShowerDigi Shower_(ME_.HMT_inTime() == -99 ? 0 : ME_.HMT_inTime(),
306  ME_.HMT_outOfTime() == -99 ? 0 : ME_.HMT_outOfTime(),
307  Hit_.CSC_DetId());
308 
309  // Set the stub number for this hit
310  // Each chamber can send up to 2 stubs per BX
311  ME_.set_stub_num(0);
312  Hit_.set_stub_num(0);
313  // See if matching hit is already in event record: exact duplicate, or from neighboring sector
314  bool exact_duplicate = false;
315  bool neighbor_duplicate = false;
316  for (auto const& iHit : *res_hit) {
317  if (iHit.Is_CSC() == 1 && Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() &&
318  Hit_.Station() == iHit.Station() && Hit_.Chamber() == iHit.Chamber() &&
319  (Hit_.Ring() % 3) == (iHit.Ring() % 3)) { // ME1/1a and ME1/1b (rings "4" and 1) are the same chamber
320 
321  if (Hit_.Ring() == iHit.Ring() && Hit_.Strip() == iHit.Strip() && Hit_.Wire() == iHit.Wire()) {
322  exact_duplicate = (Hit_.Neighbor() == iHit.Neighbor());
323  neighbor_duplicate = (Hit_.Neighbor() != iHit.Neighbor());
324  } else if (Hit_.Neighbor() == iHit.Neighbor()) {
325  ME_.set_stub_num(ME_.Stub_num() + 1);
326  Hit_.set_stub_num(Hit_.Stub_num() + 1);
327  }
328  }
329  } // End loop: for (auto const & iHit : *res_hit)
330 
331  // 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
332  if (Hit_.BX() > 3 or Hit_.BX() < -3) {
333  edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCTs with out-of-range BX! BX " << Hit_.BX() << ", endcap "
334  << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector " << Hit_.Sector()
335  << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
336  << Hit_.Chamber() << ", strip " << Hit_.Strip() << ", wire " << Hit_.Wire()
337  << std::endl;
338  return true;
339  }
340 
341  if (exact_duplicate)
342  edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate LCTs: BX " << Hit_.BX() << ", endcap "
343  << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector " << Hit_.Sector()
344  << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
345  << Hit_.Chamber() << ", strip " << Hit_.Strip() << ", wire " << Hit_.Wire()
346  << std::endl;
347 
348  (res->at(iOut)).push_ME(ME_);
349  if (!exact_duplicate && Hit_.Valid() == 1)
350  res_hit->push_back(Hit_);
351  if (!exact_duplicate && !neighbor_duplicate &&
352  Hit_.Valid() == 1) // Don't write duplicate LCTs from adjacent sectors
353  res_LCT->insertDigi(Hit_.CSC_DetId(), Hit_.CreateCSCCorrelatedLCTDigi(isRun3));
354  if (ME_.HMV() == 1) { // Only write when HMT valid bit is set to 1
355  res_shower->insertDigi(Hit_.CSC_DetId(), Shower_);
356  }
357  // Finished with unpacking one ME Data Record
358  return true;
359 
360  } // End bool MEBlockUnpacker::unpack
361 
362  // bool MEBlockPacker::pack(const Block& block, UnpackerCollections *coll) {
363  // std::cout << "Inside MEBlockPacker::pack" << std::endl;
364  // return true;
365  // } // End bool MEBlockPacker::pack
366 
367  } // End namespace emtf
368  } // End namespace stage2
369 } // End namespace l1t
370 
372 // DEFINE_L1T_PACKER(l1t::stage2::MEBlockPacker);
void set_bxe(int bits)
Definition: ME.h:57
int HMT_outOfTime() const
Definition: ME.h:117
int HMT_inTime() const
Definition: ME.h:116
void set_neighbor(int bits)
Definition: EMTFHit.h:147
void set_af(int bits)
Definition: ME.h:69
void set_bc0(int bits)
Definition: ME.h:56
int Strip() const
Definition: ME.h:95
int Frame() const
Definition: ME.h:109
int Slope() const
Definition: ME.h:112
int Wire() const
Definition: EMTFHit.h:221
unsigned int getAlgoVersion()
Definition: Unpacker.h:18
void ImportME(EMTFHit &_hit, const l1t::emtf::ME _ME, const int _endcap, const int _evt_sector)
void set_stub_num(int bits)
Definition: EMTFHit.h:180
void set_station(int bits)
Definition: EMTFHit.h:136
int CSC_ID() const
Definition: ME.h:94
int Neighbor() const
Definition: EMTFHit.h:215
void set_vp(int bits)
Definition: ME.h:71
int Station() const
Definition: ME.h:105
Definition: Event.h:15
void insertDigi(const IndexType &index, const DigiType &digi)
insert a digi for a given DetUnit
delete x;
Definition: CaloConfig.h:22
int Valid() const
Definition: EMTFHit.h:235
void set_epc(int bits)
Definition: ME.h:68
Log< level::Error, false > LogError
CSCCorrelatedLCTDigi CreateCSCCorrelatedLCTDigi(const bool isRun3) const
Definition: EMTFHit.cc:75
void set_hmv(int bits)
Definition: ME.h:80
void set_wire(int bits)
Definition: ME.h:53
std::vector< int > convert_ME_location(int _station, int _csc_ID, int _sector, bool _csc_ID_shift=false)
Definition: EMTFBlockME.cc:79
Definition: Electron.h:6
void set_ring(int bits)
Definition: EMTFHit.h:137
int CSC_ID() const
Definition: EMTFHit.h:212
void set_eighth_strip(int bits)
Definition: ME.h:76
int LR() const
Definition: ME.h:93
void add_format_error()
Definition: ME.h:85
void set_tbin(int bits)
Definition: ME.h:72
virtual int checkFormat(const Block &block)
Definition: EMTFBlockME.cc:34
bool unpack(const Block &block, UnpackerCollections *coll) override
Definition: EMTFBlockME.cc:148
void set_se(int bits)
Definition: ME.h:66
void set_stub_num(int bits)
Definition: ME.h:84
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
void set_csc_ID(int bits)
Definition: EMTFHit.h:144
void set_quality(int bits)
Definition: ME.h:54
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_csc_ID(int bits)
Definition: ME.h:59
void set_afef(int bits)
Definition: ME.h:65
void set_run3_pattern(int bits)
Definition: ME.h:78
int Strip() const
Definition: EMTFHit.h:222
void set_afff(int bits)
Definition: ME.h:61
void set_nit(int bits)
Definition: ME.h:63
void set_frame(int bits)
Definition: ME.h:74
void set_slope(int bits)
Definition: ME.h:77
void set_strip(int bits)
Definition: ME.h:60
void set_lr(int bits)
Definition: ME.h:58
void set_sector(int bits)
Definition: EMTFHit.h:138
int Endcap() const
Definition: EMTFHit.h:203
int Station() const
Definition: EMTFHit.h:204
void set_hmt_inTime(int bits)
Definition: ME.h:81
int calc_ring(int station, int csc_ID, int strip)
Definition: TrackTools.cc:5
int Stub_num() const
Definition: EMTFHit.h:263
int Chamber() const
Definition: EMTFHit.h:211
int HMV() const
Definition: ME.h:115
CSCDetId CSC_DetId() const
Definition: EMTFHit.h:128
void set_cik(int bits)
Definition: ME.h:62
void set_station(int bits)
Definition: ME.h:70
#define DEFINE_L1T_UNPACKER(type)
int Ring() const
Definition: EMTFHit.h:205
Definition: errors.py:1
void set_me_bxn(int bits)
Definition: ME.h:64
uint16_t GetHexBits(uint16_t word, uint16_t lowBit, uint16_t highBit)
void set_sm(int bits)
Definition: ME.h:67
Log< level::Warning, false > LogWarning
void set_quarter_strip(int bits)
Definition: ME.h:75
void set_hmt_outOfTime(int bits)
Definition: ME.h:82
int Stub_num() const
Definition: ME.h:119
void set_clct_pattern(int bits)
Definition: ME.h:55
void set_subsector(int bits)
Definition: EMTFHit.h:141
int Sector() const
Definition: EMTFHit.h:206
A container for a generic type of digis indexed by some index, implemented with a map<IndexType...