CMS 3D CMS Logo

EMTFBlockGEM.cc
Go to the documentation of this file.
1 // Code to unpack the "GEM Data Record"
2 
4 
5 #include "EMTFCollections.h"
6 #include "EMTFUnpackerTools.h"
7 
8 namespace l1t {
9  namespace stage2 {
10  namespace emtf {
11 
12  class GEMBlockUnpacker : public Unpacker {
13  public:
14  virtual int checkFormat(const Block& block);
15  // virtual bool checkFormat() override; // Return "false" if block format does not match expected format
16  bool unpack(const Block& block, UnpackerCollections* coll) override;
17  // virtual bool packBlock(const Block& block, UnpackerCollections *coll) override;
18  };
19 
20  // class GEMBlockPacker : public Packer {
21  // public:
22  // virtual bool unpack(const Block& block, UnpackerCollections *coll) override;
23  // };
24 
25  } // namespace emtf
26  } // namespace stage2
27 } // namespace l1t
28 
29 namespace l1t {
30  namespace stage2 {
31  namespace emtf {
32 
34  auto payload = block.payload();
35  int errors = 0;
36 
37  // Check the number of 16-bit words
38  if (payload.size() != 4) {
39  errors += 1;
40  edm::LogError("L1T|EMTF") << "Payload size in 'GEM Data Record' is different than expected";
41  }
42 
43  // Check that each word is 16 bits
44  for (size_t i = 0; i < 4; ++i) {
45  if (GetHexBits(payload[i], 16, 31) != 0) {
46  errors += 1;
47  edm::LogError("L1T|EMTF") << "Payload[" << i << "] has more than 16 bits in 'GEM Data Record'";
48  }
49  }
50 
51  uint16_t GEMa = payload[0];
52  uint16_t GEMb = payload[1];
53  uint16_t GEMc = payload[2];
54  uint16_t GEMd = payload[3];
55 
56  // Check Format
57  if (GetHexBits(GEMa, 15, 15) != 1) {
58  errors += 1;
59  edm::LogError("L1T|EMTF") << "Format identifier bits in GEMa are incorrect";
60  }
61  if (GetHexBits(GEMb, 15, 15) != 1) {
62  errors += 1;
63  edm::LogError("L1T|EMTF") << "Format identifier bits in GEMb are incorrect";
64  }
65  if (GetHexBits(GEMc, 15, 15) != 1) {
66  errors += 1;
67  edm::LogError("L1T|EMTF") << "Format identifier bits in GEMc are incorrect";
68  }
69  if (GetHexBits(GEMd, 15, 15) != 0) {
70  errors += 1;
71  edm::LogError("L1T|EMTF") << "Format identifier bits in GEMd are incorrect";
72  }
73 
74  return errors;
75  }
76 
91  int& ring,
92  int& sector,
93  int& subsector,
94  int& neighbor,
95  int& layer, // is this correct for the GEM case?
96  const int evt_sector,
97  const int cluster_id, // used to differentiate between GEM layer 1/2
98  const int link) {
99  station =
100  1; // station is not encoded in the GEM frame for now. Set station = 1 since we only have GE1/1 for Run 3.
101  ring = 1; // GEMs are only in GE1/1 and GE2/1
102  sector = -99;
103  subsector = -99;
104  neighbor = -99;
105  layer = -99; // the GEM layer is 1 or 2, depending on the cluster ID
106 
107  // Neighbor indicated by link == 6
108  sector = (link != 6 ? evt_sector : (evt_sector == 1 ? 6 : evt_sector - 1));
109  subsector = (link != 6 ? link : 0); // TODO: verify subsector 0 in the neighbouring sector?
110  neighbor = (link == 6 ? 1 : 0); // TODO: verify that 6 is for the neighbour, not 0 (as written in EMTFBlockRPC)
111  layer = (cluster_id % 8); // + 1 if layer should be 1 or 2, otherwise layer is 0 or 1
112  }
113 
123  // std::cout << "Inside EMTFBlockGEM.cc: unpack" << std::endl;
124 
125  // Get the payload for this block, made up of 16-bit words (0xffff)
126  // Format defined in MTF7Payload::getBlock() in src/Block.cc
127  // payload[0] = bits 0-15, payload[1] = 16-31, payload[3] = 32-47, etc.
128  auto payload = block.payload();
129 
130  // Check Format of Payload
131  l1t::emtf::GEM GEM_;
132  for (int err = 0; err < checkFormat(block); ++err) {
133  GEM_.add_format_error();
134  }
135 
136  // Assign payload to 16-bit words
137  uint16_t GEMa = payload[0];
138  uint16_t GEMb = payload[1];
139  uint16_t GEMc = payload[2];
140  uint16_t GEMd = payload[3];
141 
142  // res is a pointer to a collection of EMTFDaqOut class objects
143  // There is one EMTFDaqOut for each MTF7 (60 deg. sector) in the event
145  res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
146  int iOut = res->size() - 1;
147 
148  EMTFHitCollection* res_hit;
149  res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
150  EMTFHit Hit_;
151 
152  // TODO: Verify this is correct for GEM
154  res_GEM = static_cast<EMTFCollections*>(coll)->getEMTFGEMPadClusters();
155 
157  // Unpack the GEM Data Record
159 
160  GEM_.set_pad(GetHexBits(GEMa, 0, 8));
161  GEM_.set_partition(GetHexBits(GEMa, 9, 11));
162  GEM_.set_cluster_size(GetHexBits(GEMa, 12, 14));
163 
164  GEM_.set_cluster_id(GetHexBits(GEMb, 8, 11));
165  GEM_.set_link(GetHexBits(GEMb, 12, 14));
166 
167  GEM_.set_gem_bxn(GetHexBits(GEMc, 0, 11));
168  GEM_.set_bc0(GetHexBits(GEMc, 14, 14));
169 
170  GEM_.set_tbin(GetHexBits(GEMd, 0, 2));
171  GEM_.set_vp(GetHexBits(GEMd, 3, 3));
172 
173  // GEM_.set_dataword(uint64_t dataword);
174 
175  // Convert specially-encoded GEM quantities
176  // TODO: is the RPC or CSC method for this function better... - JS 06.07.20
177  int _station, _ring, _sector, _subsector, _neighbor, _layer;
178  convert_GEM_location(_station,
179  _ring,
180  _sector,
181  _subsector,
182  _neighbor,
183  _layer,
184  (res->at(iOut)).PtrEventHeader()->Sector(),
185  GEM_.ClusterID(),
186  GEM_.Link());
187 
188  // Rotate by 20 deg to match GEM convention in CMSSW) // FIXME VERIFY
189  // int _sector_gem = (_subsector < 5) ? _sector : (_sector % 6) + 1; //
190  int _sector_gem = _sector;
191  // Rotate by 2 to match GEM convention in CMSSW (GEMDetId.h) // FIXME VERIFY
192  int _subsector_gem = ((_subsector + 1) % 6) + 1;
193  // Define chamber number) // FIXME VERIFY
194  int _chamber = (_sector_gem - 1) * 6 + _subsector_gem;
195  // Define CSC-like subsector) // FIXME WHY?? VERIFY
196  int _subsector_csc = (_station != 1) ? 0 : ((_chamber % 6 > 2) ? 1 : 2);
197 
198  Hit_.set_station(_station);
199  Hit_.set_ring(_ring);
200  Hit_.set_sector(_sector);
201  Hit_.set_subsector(_subsector_csc);
202  Hit_.set_chamber(_chamber);
203  Hit_.set_neighbor(_neighbor);
204 
205  // Fill the EMTFHit
206  ImportGEM(Hit_, GEM_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());
207 
208  // Set the stub number for this hit
209  // Each chamber can send up to 2 stubs per BX // FIXME is this true for GEM, are stubs relevant for GEMs?
210  // Also count stubs in corresponding CSC chamber; GEM hit counting is on top of LCT counting
211  Hit_.set_stub_num(0);
212  // See if matching hit is already in event record
213  bool exact_duplicate = false;
214  for (auto const& iHit : *res_hit) {
215  if (Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() && Hit_.Station() == iHit.Station() &&
216  Hit_.Chamber() == iHit.Chamber()) {
217  if ((iHit.Is_CSC() == 1 && iHit.Ring() == 2) ||
218  (iHit.Is_GEM() == 1)) { // Copied from RPC, but GEM has no ring 2/3...
219  if (Hit_.Neighbor() == iHit.Neighbor()) {
220  Hit_.set_stub_num(Hit_.Stub_num() + 1);
221  if (iHit.Is_GEM() == 1 && iHit.Ring() == Hit_.Ring() && iHit.Roll() == Hit_.Roll() &&
222  iHit.Pad() == Hit_.Pad()) {
223  exact_duplicate = true;
224  }
225  }
226  }
227  }
228  } // End loop: for (auto const & iHit : *res_hit)
229 
230  // TODO: Re-enable once GEM TP data format is fixed
231  // if (exact_duplicate)
232  // edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate GEM digis: BX " << Hit_.BX() << ", endcap "
233  // << Hit_.Endcap() << ", station " << Hit_.Station() << ", neighbor "
234  // << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber " << Hit_.Chamber()
235  // << ", roll " << Hit_.Roll() << ", pad " << Hit_.Pad() << std::endl;
236 
237  (res->at(iOut)).push_GEM(GEM_);
238  if (!exact_duplicate)
239  res_hit->push_back(Hit_);
240 
241  if (!exact_duplicate)
242  res_GEM->insertDigi(Hit_.GEM_DetId(), Hit_.CreateGEMPadDigiCluster());
243 
244  // Finished with unpacking one GEM Data Record
245  return true;
246 
247  } // End bool GEMBlockUnpacker::unpack
248 
249  // bool GEMBlockPacker::pack(const Block& block, UnpackerCollections *coll) {
250  // std::cout << "Inside GEMBlockPacker::pack" << std::endl;
251  // return true;
252  // } // End bool GEMBlockPacker::pack
253 
254  } // End namespace emtf
255  } // End namespace stage2
256 } // End namespace l1t
257 
259 // DEFINE_L1T_PACKER(l1t::stage2::emtf::GEMBlockPacker);
void set_neighbor(int bits)
Definition: EMTFHit.h:147
void set_stub_num(int bits)
Definition: EMTFHit.h:180
void set_station(int bits)
Definition: EMTFHit.h:136
void set_gem_bxn(const int bits)
Definition: GEM.h:35
int Neighbor() const
Definition: EMTFHit.h:215
GEMPadDigiCluster CreateGEMPadDigiCluster() const
Definition: EMTFHit.cc:98
Definition: Event.h:15
delete x;
Definition: CaloConfig.h:22
virtual int checkFormat(const Block &block)
Definition: EMTFBlockGEM.cc:33
Log< level::Error, false > LogError
void ImportGEM(EMTFHit &_hit, const l1t::emtf::GEM &_GEM, const int _endcap, const int _evt_sector)
int Roll() const
Definition: EMTFHit.h:214
Definition: Electron.h:6
void set_ring(int bits)
Definition: EMTFHit.h:137
constexpr std::array< uint8_t, layerIndexSize > layer
int Pad() const
Repurpose "strip" as GEM pad for GEM sourced hits.
Definition: EMTFHit.h:248
void set_bc0(const int bits)
Definition: GEM.h:36
void set_link(const int bits)
Definition: GEM.h:34
void set_tbin(const int bits)
Definition: GEM.h:37
std::vector< EMTFHit > EMTFHitCollection
Definition: EMTFHit.h:366
void set_cluster_id(const int bits)
Definition: GEM.h:33
int ClusterID() const
Returns the the cluster ID within the link.
Definition: GEM.h:49
std::vector< EMTFDaqOut > EMTFDaqOutCollection
Definition: EMTFDaqOut.h:179
int BX() const
Definition: EMTFHit.h:262
void set_partition(const int bits)
Definition: GEM.h:31
bool unpack(const Block &block, UnpackerCollections *coll) override
Unpack the GEM payload in the EMTF DAQ payload.
void set_vp(const int bits)
Definition: GEM.h:38
void set_pad(const int bits)
Definition: GEM.h:30
void add_format_error()
Definition: GEM.h:39
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
GEMDetId GEM_DetId() const
Definition: EMTFHit.h:130
void convert_GEM_location(int &station, int &ring, int &sector, int &subsector, int &neighbor, int &layer, const int evt_sector, const int cluster_id, const int link)
Converts station, ring, sector, subsector, neighbor, and segment from the GEM output.
Definition: EMTFBlockGEM.cc:90
#define DEFINE_L1T_UNPACKER(type)
int Ring() const
Definition: EMTFHit.h:205
Definition: errors.py:1
uint16_t GetHexBits(uint16_t word, uint16_t lowBit, uint16_t highBit)
void set_chamber(int bits)
Definition: EMTFHit.h:143
void set_subsector(int bits)
Definition: EMTFHit.h:141
void set_cluster_size(const int bits)
Definition: GEM.h:32
int Link() const
Returns the input link of the cluster.
Definition: GEM.h:51