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
0009 namespace l1t {
0010 namespace stage2 {
0011 namespace emtf {
0012
0013 class MEBlockUnpacker : public Unpacker {
0014 public:
0015 virtual int checkFormat(const Block& block);
0016 bool unpack(const Block& block,
0017 UnpackerCollections* coll) override;
0018
0019 };
0020
0021
0022
0023
0024
0025
0026 }
0027 }
0028 }
0029
0030 namespace l1t {
0031 namespace stage2 {
0032 namespace emtf {
0033
0034 int MEBlockUnpacker::checkFormat(const Block& block) {
0035 auto payload = block.payload();
0036 int errors = 0;
0037
0038
0039 if (payload.size() != 4) {
0040 errors += 1;
0041 edm::LogError("L1T|EMTF") << "Payload size in 'ME Data Record' is different than expected";
0042 }
0043
0044
0045 for (unsigned int i = 0; i < 4; i++) {
0046 if (GetHexBits(payload[i], 16, 31) != 0) {
0047 errors += 1;
0048 edm::LogError("L1T|EMTF") << "Payload[" << i << "] has more than 16 bits in 'ME Data Record'";
0049 }
0050 }
0051
0052 uint16_t MEa = payload[0];
0053 uint16_t MEb = payload[1];
0054 uint16_t MEc = payload[2];
0055 uint16_t MEd = payload[3];
0056
0057
0058 if (GetHexBits(MEa, 15, 15) != 1) {
0059 errors += 1;
0060 edm::LogError("L1T|EMTF") << "Format identifier bits in MEa are incorrect";
0061 }
0062 if (GetHexBits(MEb, 15, 15) != 1) {
0063 errors += 1;
0064 edm::LogError("L1T|EMTF") << "Format identifier bits in MEb are incorrect";
0065 }
0066 if (GetHexBits(MEc, 15, 15) != 0) {
0067 errors += 1;
0068 edm::LogError("L1T|EMTF") << "Format identifier bits in MEc are incorrect";
0069 }
0070 if (GetHexBits(MEd, 15, 15) != 0) {
0071 errors += 1;
0072 edm::LogError("L1T|EMTF") << "Format identifier bits in MEd are incorrect";
0073 }
0074
0075 return errors;
0076 }
0077
0078
0079 std::vector<int> convert_ME_location(int _station, int _csc_ID, int _sector, bool _csc_ID_shift = false) {
0080 int new_sector = _sector;
0081 int new_csc_ID = _csc_ID;
0082 if (_csc_ID_shift)
0083 new_csc_ID += 1;
0084 if (_station == 0) {
0085 int arr[] = {1, new_csc_ID, new_sector, 1, 0};
0086 std::vector<int> vec(arr, arr + 5);
0087 return vec;
0088 } else if (_station == 1) {
0089 int arr[] = {1, new_csc_ID, new_sector, 2, 0};
0090 std::vector<int> vec(arr, arr + 5);
0091 return vec;
0092 } else if (_station <= 4) {
0093 int arr[] = {_station, new_csc_ID, new_sector, -1, 0};
0094 std::vector<int> vec(arr, arr + 5);
0095 return vec;
0096 } else if (_station == 5) {
0097 new_sector = (_sector != 1) ? _sector - 1 : 6;
0098 } else {
0099 int arr[] = {_station, _csc_ID, _sector, -99, -99};
0100 std::vector<int> vec(arr, arr + 5);
0101 return vec;
0102 }
0103
0104
0105 if (new_csc_ID == 1) {
0106 int arr[] = {1, 3, new_sector, 2, 1};
0107 std::vector<int> vec(arr, arr + 5);
0108 return vec;
0109 } else if (new_csc_ID == 2) {
0110 int arr[] = {1, 6, new_sector, 2, 1};
0111 std::vector<int> vec(arr, arr + 5);
0112 return vec;
0113 } else if (new_csc_ID == 3) {
0114 int arr[] = {1, 9, new_sector, 2, 1};
0115 std::vector<int> vec(arr, arr + 5);
0116 return vec;
0117 } else if (new_csc_ID == 4) {
0118 int arr[] = {2, 3, new_sector, -1, 1};
0119 std::vector<int> vec(arr, arr + 5);
0120 return vec;
0121 } else if (new_csc_ID == 5) {
0122 int arr[] = {2, 9, new_sector, -1, 1};
0123 std::vector<int> vec(arr, arr + 5);
0124 return vec;
0125 } else if (new_csc_ID == 6) {
0126 int arr[] = {3, 3, new_sector, -1, 1};
0127 std::vector<int> vec(arr, arr + 5);
0128 return vec;
0129 } else if (new_csc_ID == 7) {
0130 int arr[] = {3, 9, new_sector, -1, 1};
0131 std::vector<int> vec(arr, arr + 5);
0132 return vec;
0133 } else if (new_csc_ID == 8) {
0134 int arr[] = {4, 3, new_sector, -1, 1};
0135 std::vector<int> vec(arr, arr + 5);
0136 return vec;
0137 } else if (new_csc_ID == 9) {
0138 int arr[] = {4, 9, new_sector, -1, 1};
0139 std::vector<int> vec(arr, arr + 5);
0140 return vec;
0141 } else {
0142 int arr[] = {_station, _csc_ID, _sector, -99, -99};
0143 std::vector<int> vec(arr, arr + 5);
0144 return vec;
0145 }
0146 }
0147
0148 bool MEBlockUnpacker::unpack(const Block& block, UnpackerCollections* coll) {
0149
0150
0151
0152
0153
0154 auto payload = block.payload();
0155
0156
0157 uint16_t MEa = payload[0];
0158 uint16_t MEb = payload[1];
0159 uint16_t MEc = payload[2];
0160 uint16_t MEd = payload[3];
0161
0162
0163 l1t::emtf::ME ME_;
0164 for (int err = 0; err < checkFormat(block); err++)
0165 ME_.add_format_error();
0166
0167
0168
0169 EMTFDaqOutCollection* res;
0170 res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
0171 int iOut = res->size() - 1;
0172
0173 EMTFHitCollection* res_hit;
0174 res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
0175 EMTFHit Hit_;
0176
0177 CSCCorrelatedLCTDigiCollection* res_LCT;
0178 res_LCT = static_cast<EMTFCollections*>(coll)->getEMTFLCTs();
0179
0180 CSCShowerDigiCollection* res_shower;
0181 res_shower = static_cast<EMTFCollections*>(coll)->getEMTFCSCShowers();
0182
0183
0184
0185
0186
0187
0188
0189 bool run3_DAQ_format =
0190 (getAlgoVersion() >= 11460);
0191 bool reducedDAQWindow =
0192 (getAlgoVersion() >=
0193 11656);
0194
0195
0196 ME_.set_clct_pattern(GetHexBits(MEa, 0, 3));
0197 ME_.set_quality(GetHexBits(MEa, 4, 7));
0198 ME_.set_wire(GetHexBits(MEa, 8, 14));
0199
0200 ME_.set_strip(GetHexBits(MEb, 0, 7));
0201 ME_.set_csc_ID(GetHexBits(MEb, 8, 11));
0202 ME_.set_lr(GetHexBits(MEb, 12, 12));
0203 ME_.set_bxe(GetHexBits(MEb, 13, 13));
0204 ME_.set_bc0(GetHexBits(MEb, 14, 14));
0205
0206 ME_.set_me_bxn(GetHexBits(MEc, 0, 11));
0207 ME_.set_nit(GetHexBits(MEc, 12, 12));
0208 ME_.set_cik(GetHexBits(MEc, 13, 13));
0209 ME_.set_afff(GetHexBits(MEc, 14, 14));
0210
0211 if (reducedDAQWindow)
0212 ME_.set_tbin(GetHexBits(MEd, 0, 2) + 1);
0213 else
0214 ME_.set_tbin(GetHexBits(MEd, 0, 2));
0215 ME_.set_vp(GetHexBits(MEd, 3, 3));
0216 ME_.set_station(GetHexBits(MEd, 4, 6));
0217 ME_.set_af(GetHexBits(MEd, 7, 7));
0218 ME_.set_epc(GetHexBits(MEd, 8, 11));
0219 ME_.set_sm(GetHexBits(MEd, 12, 12));
0220 ME_.set_se(GetHexBits(MEd, 13, 13));
0221 ME_.set_afef(GetHexBits(MEd, 14, 14));
0222
0223
0224
0225
0226 bool csc_ID_shift = (getAlgoVersion() <=
0227 8348);
0228
0229 std::vector<int> conv_vals =
0230 convert_ME_location(ME_.Station(), ME_.CSC_ID(), (res->at(iOut)).PtrEventHeader()->Sector(), csc_ID_shift);
0231
0232 Hit_.set_station(conv_vals.at(0));
0233 Hit_.set_csc_ID(conv_vals.at(1));
0234 Hit_.set_sector(conv_vals.at(2));
0235 Hit_.set_subsector(conv_vals.at(3));
0236 Hit_.set_neighbor(conv_vals.at(4));
0237 Hit_.set_ring(L1TMuonEndCap::calc_ring(Hit_.Station(), Hit_.CSC_ID(), ME_.Strip()));
0238
0239 if (Hit_.Station() < 1 || Hit_.Station() > 4)
0240 edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCT station = " << Hit_.Station()
0241 << ", outside proper [1, 4] range" << std::endl;
0242 if (Hit_.CSC_ID() < 1 || Hit_.CSC_ID() > 9)
0243 edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCT CSC ID = " << Hit_.CSC_ID()
0244 << ", outside proper [1, 9] range" << std::endl;
0245 if (Hit_.Sector() < 1 || Hit_.Sector() > 6)
0246 edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCT sector = " << Hit_.Sector()
0247 << ", outside proper [1, 6] range" << std::endl;
0248
0249
0250 bool isOTMB = (Hit_.Ring() == 1 or
0251 Hit_.Ring() == 4);
0252
0253 bool isRun3 =
0254 isOTMB and run3_DAQ_format;
0255
0256 if (run3_DAQ_format) {
0257 ME_.set_quality(GetHexBits(MEa, 4, 6));
0258 ME_.set_quarter_strip(GetHexBits(MEa, 7, 7));
0259
0260 ME_.set_frame(GetHexBits(MEc, 12, 12));
0261
0262 ME_.set_eighth_strip(GetHexBits(MEd, 13, 13));
0263
0264 if (isOTMB) {
0265
0266 ME_.set_slope(GetHexBits(MEd, 8, 11));
0267
0268
0269
0270 const unsigned slopeList[32] = {10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 2,
0271 10, 10, 10, 9, 9, 9, 7, 7, 7, 5, 5, 5, 3, 3, 3, 3};
0272
0273
0274 unsigned slope_and_sign(ME_.Slope());
0275 if (ME_.LR() == 1) {
0276 slope_and_sign += 16;
0277 }
0278 unsigned run2_converted_PID = slopeList[slope_and_sign];
0279
0280 ME_.set_clct_pattern(run2_converted_PID);
0281
0282 } else {
0283 ME_.set_clct_pattern(GetHexBits(MEd, 8, 11));
0284 }
0285
0286
0287 if (ME_.Frame() == 1) {
0288
0289 ME_.set_run3_pattern(GetHexBits(MEa, 0, 0));
0290
0291
0292 ME_.set_mus_inTime(GetHexBits(MEb, 13, 13, MEa, 1, 1));
0293
0294
0295 ME_.set_mus_outOfTime(GetHexBits(MEa, 2, 3));
0296
0297 ME_.set_musv(GetHexBits(MEd, 7, 7));
0298 } else {
0299 ME_.set_run3_pattern(GetHexBits(MEa, 0, 3));
0300
0301 ME_.set_bxe(GetHexBits(MEb, 13, 13));
0302
0303 ME_.set_af(GetHexBits(MEd, 7, 7));
0304 }
0305 }
0306
0307
0308 ImportME(Hit_, ME_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());
0309
0310
0311
0312 ME_.set_stub_num(0);
0313 Hit_.set_stub_num(0);
0314
0315 bool exact_duplicate = false;
0316 bool neighbor_duplicate = false;
0317 for (auto const& iHit : *res_hit) {
0318 if (iHit.Is_CSC() == 1 && Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() &&
0319 Hit_.Station() == iHit.Station() && Hit_.Chamber() == iHit.Chamber() &&
0320 (Hit_.Ring() % 3) == (iHit.Ring() % 3)) {
0321
0322 if (Hit_.Ring() == iHit.Ring() && Hit_.Strip() == iHit.Strip() && Hit_.Wire() == iHit.Wire()) {
0323 exact_duplicate = (Hit_.Neighbor() == iHit.Neighbor());
0324 neighbor_duplicate = (Hit_.Neighbor() != iHit.Neighbor());
0325 } else if (Hit_.Neighbor() == iHit.Neighbor()) {
0326 ME_.set_stub_num(ME_.Stub_num() + 1);
0327 Hit_.set_stub_num(Hit_.Stub_num() + 1);
0328 }
0329 }
0330 }
0331
0332
0333 if (Hit_.BX() > 3 or Hit_.BX() < -3) {
0334 edm::LogWarning("L1T|EMTF") << "EMTF unpacked LCTs with out-of-range BX! BX " << Hit_.BX() << ", endcap "
0335 << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector " << Hit_.Sector()
0336 << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
0337 << Hit_.Chamber() << ", strip " << Hit_.Strip() << ", wire " << Hit_.Wire()
0338 << std::endl;
0339 return true;
0340 }
0341
0342 if (exact_duplicate)
0343 edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate LCTs: BX " << Hit_.BX() << ", endcap "
0344 << Hit_.Endcap() << ", station " << Hit_.Station() << ", sector " << Hit_.Sector()
0345 << ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
0346 << Hit_.Chamber() << ", strip " << Hit_.Strip() << ", wire " << Hit_.Wire()
0347 << std::endl;
0348
0349
0350 if (Hit_.Quality() == 0)
0351 Hit_.set_valid(0);
0352
0353 (res->at(iOut)).push_ME(ME_);
0354 if (!exact_duplicate && Hit_.Valid() == 1)
0355 res_hit->push_back(Hit_);
0356 if (!exact_duplicate && !neighbor_duplicate &&
0357 Hit_.Valid() == 1)
0358 res_LCT->insertDigi(Hit_.CSC_DetId(), Hit_.CreateCSCCorrelatedLCTDigi(isRun3));
0359 if (Hit_.Muon_shower_valid() == 1) {
0360 res_shower->insertDigi(Hit_.CSC_DetId(), Hit_.CreateCSCShowerDigi());
0361 }
0362
0363 return true;
0364
0365 }
0366
0367
0368
0369
0370
0371
0372 }
0373 }
0374 }
0375
0376 DEFINE_L1T_UNPACKER(l1t::stage2::emtf::MEBlockUnpacker);
0377