File indexing completed on 2024-09-07 04:36:14
0001
0002
0003 #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h"
0004
0005 #include "EMTFCollections.h"
0006 #include "EMTFUnpackerTools.h"
0007
0008 namespace l1t {
0009 namespace stage2 {
0010 namespace emtf {
0011
0012 class GEMBlockUnpacker : public Unpacker {
0013 public:
0014 virtual int checkFormat(const Block& block);
0015
0016 bool unpack(const Block& block, UnpackerCollections* coll) override;
0017
0018 };
0019
0020
0021
0022
0023
0024
0025 }
0026 }
0027 }
0028
0029 namespace l1t {
0030 namespace stage2 {
0031 namespace emtf {
0032
0033 int GEMBlockUnpacker::checkFormat(const Block& block) {
0034 auto payload = block.payload();
0035 int errors = 0;
0036
0037
0038 if (payload.size() != 4) {
0039 errors += 1;
0040 edm::LogError("L1T|EMTF") << "Payload size in 'GEM Data Record' is different than expected";
0041 }
0042
0043
0044 for (size_t i = 0; i < 4; ++i) {
0045 if (GetHexBits(payload[i], 16, 31) != 0) {
0046 errors += 1;
0047 edm::LogError("L1T|EMTF") << "Payload[" << i << "] has more than 16 bits in 'GEM Data Record'";
0048 }
0049 }
0050
0051 uint16_t GEMa = payload[0];
0052 uint16_t GEMb = payload[1];
0053 uint16_t GEMc = payload[2];
0054 uint16_t GEMd = payload[3];
0055
0056
0057 if (GetHexBits(GEMa, 15, 15) != 1) {
0058 errors += 1;
0059 edm::LogError("L1T|EMTF") << "Format identifier bits in GEMa are incorrect";
0060 }
0061 if (GetHexBits(GEMb, 15, 15) != 1) {
0062 errors += 1;
0063 edm::LogError("L1T|EMTF") << "Format identifier bits in GEMb are incorrect";
0064 }
0065 if (GetHexBits(GEMc, 15, 15) != 1) {
0066 errors += 1;
0067 edm::LogError("L1T|EMTF") << "Format identifier bits in GEMc are incorrect";
0068 }
0069 if (GetHexBits(GEMd, 15, 15) != 0) {
0070 errors += 1;
0071 edm::LogError("L1T|EMTF") << "Format identifier bits in GEMd are incorrect";
0072 }
0073
0074 return errors;
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 void convert_GEM_location(int& station,
0091 int& ring,
0092 int& sector,
0093 int& subsector,
0094 int& neighbor,
0095 int& layer,
0096 const int evt_sector,
0097 const int cluster_id,
0098 const int link) {
0099 station =
0100 1;
0101 ring = 1;
0102 sector = -99;
0103 subsector = -99;
0104 neighbor = -99;
0105 layer = -99;
0106
0107
0108 sector = (link != 4 ? evt_sector : (evt_sector == 1 ? 6 : evt_sector - 1));
0109 subsector = (link < 4 ? link : (link == 4 ? 5 : link - 1));
0110 neighbor = (link == 4 ? 1 : 0);
0111 layer = (cluster_id / 4) % 2 + 1;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 bool GEMBlockUnpacker::unpack(const Block& block, UnpackerCollections* coll) {
0123
0124
0125
0126
0127
0128 auto payload = block.payload();
0129
0130
0131
0132 bool run3_DAQ_format =
0133 (getAlgoVersion() >=
0134 11546);
0135 bool reducedDAQWindow =
0136 (getAlgoVersion() >=
0137 11656);
0138
0139 int nTPs = run3_DAQ_format ? 2 : 1;
0140
0141
0142 l1t::emtf::GEM GEM_;
0143 for (int err = 0; err < checkFormat(block); ++err) {
0144 GEM_.add_format_error();
0145 }
0146
0147
0148 uint16_t GEMa = payload[0];
0149 uint16_t GEMb = payload[1];
0150 uint16_t GEMc = payload[2];
0151 uint16_t GEMd = payload[3];
0152
0153
0154 for (int i = 1; i <= nTPs; i++) {
0155
0156
0157 EMTFDaqOutCollection* res;
0158 res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
0159 int iOut = res->size() - 1;
0160
0161 EMTFHitCollection* res_hit;
0162 res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
0163 EMTFHit Hit_;
0164
0165 GEMPadDigiClusterCollection* res_GEM;
0166 res_GEM = static_cast<EMTFCollections*>(coll)->getEMTFGEMPadClusters();
0167
0168
0169
0170
0171 if (run3_DAQ_format) {
0172 if (i == 1) {
0173 GEM_.set_pad(GetHexBits(GEMa, 0, 8));
0174 GEM_.set_partition(GetHexBits(GEMa, 9, 11));
0175 GEM_.set_cluster_size(GetHexBits(GEMa, 12, 14));
0176
0177 if (reducedDAQWindow)
0178 GEM_.set_tbin(GetHexBits(GEMb, 0, 2) + 1);
0179 else
0180 GEM_.set_tbin(GetHexBits(GEMb, 0, 2));
0181 GEM_.set_vp(GetHexBits(GEMb, 3, 3));
0182 GEM_.set_bc0(GetHexBits(GEMb, 7, 7));
0183 GEM_.set_cluster_id(GetHexBits(GEMb, 8, 11));
0184 GEM_.set_link(GetHexBits(GEMb, 12, 14));
0185 } else if (i == 2) {
0186 GEM_.set_pad(GetHexBits(GEMc, 0, 8));
0187 GEM_.set_partition(GetHexBits(GEMc, 9, 11));
0188 GEM_.set_cluster_size(GetHexBits(GEMc, 12, 14));
0189
0190 if (reducedDAQWindow)
0191 GEM_.set_tbin(GetHexBits(GEMd, 0, 2) + 1);
0192 else
0193 GEM_.set_tbin(GetHexBits(GEMd, 0, 2));
0194 GEM_.set_vp(GetHexBits(GEMd, 3, 3));
0195 GEM_.set_bc0(GetHexBits(GEMd, 7, 7));
0196 GEM_.set_cluster_id(GetHexBits(GEMd, 8, 11));
0197 GEM_.set_link(GetHexBits(GEMd, 12, 14));
0198 }
0199 } else {
0200 GEM_.set_pad(GetHexBits(GEMa, 0, 8));
0201 GEM_.set_partition(GetHexBits(GEMa, 9, 11));
0202 GEM_.set_cluster_size(GetHexBits(GEMa, 12, 14));
0203
0204 GEM_.set_cluster_id(GetHexBits(GEMb, 8, 11));
0205 GEM_.set_link(GetHexBits(GEMb, 12, 14));
0206
0207 GEM_.set_gem_bxn(GetHexBits(GEMc, 0, 11));
0208 GEM_.set_bc0(GetHexBits(GEMc, 14, 14));
0209
0210 GEM_.set_tbin(GetHexBits(GEMd, 0, 2));
0211 GEM_.set_vp(GetHexBits(GEMd, 3, 3));
0212
0213
0214 }
0215
0216
0217 int _station, _ring, _sector, _subsector, _neighbor, _layer;
0218 convert_GEM_location(_station,
0219 _ring,
0220 _sector,
0221 _subsector,
0222 _neighbor,
0223 _layer,
0224 (res->at(iOut)).PtrEventHeader()->Sector(),
0225 GEM_.ClusterID(),
0226 GEM_.Link());
0227
0228 int _sector_gem = _sector;
0229 int _subsector_gem = _subsector;
0230 int _chamber = ((_sector_gem - 1) * 6 + _subsector_gem + 2) % 36 + 1;
0231
0232 int _subsector_csc = (_station != 1) ? 0 : ((_chamber % 6 > 2) ? 1 : 2);
0233
0234 Hit_.set_station(_station);
0235 Hit_.set_ring(_ring);
0236 Hit_.set_sector(_sector);
0237 Hit_.set_subsector(_subsector_csc);
0238 Hit_.set_chamber(_chamber);
0239 Hit_.set_neighbor(_neighbor);
0240 Hit_.set_layer(_layer);
0241
0242
0243 ImportGEM(Hit_, GEM_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());
0244
0245
0246
0247
0248 Hit_.set_stub_num(0);
0249
0250 bool exact_duplicate = false;
0251 for (auto const& iHit : *res_hit) {
0252 if (Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() && Hit_.Station() == iHit.Station() &&
0253 Hit_.Chamber() == iHit.Chamber()) {
0254 if ((iHit.Is_CSC() == 1 && iHit.Ring() == 2) ||
0255 (iHit.Is_GEM() == 1)) {
0256 if (Hit_.Neighbor() == iHit.Neighbor()) {
0257 Hit_.set_stub_num(Hit_.Stub_num() + 1);
0258 if (iHit.Is_GEM() == 1 && iHit.Ring() == Hit_.Ring() && iHit.Roll() == Hit_.Roll() &&
0259 iHit.Pad() == Hit_.Pad()) {
0260 exact_duplicate = true;
0261 }
0262 }
0263 }
0264 }
0265 }
0266
0267
0268 if (Hit_.BX() > 3 or Hit_.BX() < -3) {
0269 edm::LogWarning("L1T|EMTF") << "EMTF unpacked GEM digis with out-of-range BX! BX " << Hit_.BX()
0270 << ", endcap " << Hit_.Endcap() << ", station " << Hit_.Station()
0271 << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
0272 << Hit_.Chamber() << ", roll " << Hit_.Roll() << ", pad " << Hit_.Pad()
0273 << std::endl;
0274 return true;
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284 (res->at(iOut)).push_GEM(GEM_);
0285 if (!exact_duplicate and Hit_.Valid())
0286 res_hit->push_back(Hit_);
0287
0288 if (!exact_duplicate and Hit_.Valid())
0289 res_GEM->insertDigi(Hit_.GEM_DetId(), Hit_.CreateGEMPadDigiCluster());
0290
0291
0292 }
0293 return true;
0294
0295 }
0296
0297
0298
0299
0300
0301
0302 }
0303 }
0304 }
0305
0306 DEFINE_L1T_UNPACKER(l1t::stage2::emtf::GEMBlockUnpacker);
0307